> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/kyutai-labs/unmute/llms.txt
> Use this file to discover all available pages before exploring further.

# Remote Access via SSH

> Access Unmute running on a remote server from your local browser using SSH port forwarding

If you're running Unmute on a remote machine (like a GPU server) and want to access it from your local computer, you'll need to set up SSH port forwarding. This creates secure tunnels that forward traffic from your local machine to the remote server.

## Why Port Forwarding?

Browsers require either HTTPS or `localhost` to access the microphone. Even if your remote server is accessible at `http://remote-server:3000`, your browser won't allow microphone access over plain HTTP.

<Note>
  Port forwarding makes the remote server appear as `localhost` to your browser, which allows microphone access without HTTPS.
</Note>

## Port Forwarding Setup

The approach differs slightly between Docker Compose and Dockerless deployments.

### For Docker Compose

Docker Compose runs everything through Traefik on **port 80**.

<Steps>
  <Step title="Start SSH Tunnel">
    Forward port 80 from the remote server to a local port (e.g., 3333):

    ```bash theme={null}
    ssh -N -L 3333:localhost:80 unmute-box
    ```

    **Command breakdown:**

    * `-N`: Don't execute a remote command (just forward ports)
    * `-L 3333:localhost:80`: Forward local port 3333 to remote port 80
    * `unmute-box`: Your remote server hostname or IP

    <Note>
      If successful, this command produces no output and keeps running. Don't close the terminal.
    </Note>
  </Step>

  <Step title="Access in Browser">
    Open your local browser to:

    ```
    http://localhost:3333
    ```

    The browser treats this as localhost and allows microphone access.
  </Step>
</Steps>

#### Docker Compose Architecture with Port Forwarding

```mermaid theme={null}
flowchart LR
    subgraph Local_Machine
        browser[Browser]
        local_port[localhost:3333]
    end
    subgraph Remote_Server
        traefik[Traefik:80]
        frontend[Frontend:3000]
        backend[Backend:8000]
    end
    browser --> local_port
    local_port -.SSH Tunnel.-> traefik
    traefik --> frontend
    traefik --> backend
```

### For Dockerless

Dockerless deployment uses separate ports for frontend (3000) and backend (8000).

<Steps>
  <Step title="Start SSH Tunnel with Multiple Ports">
    Forward both ports in a single SSH command:

    ```bash theme={null}
    ssh -N -L 8000:localhost:8000 -L 3000:localhost:3000 unmute-box
    ```

    This forwards:

    * Local port 3000 → Remote frontend (port 3000)
    * Local port 8000 → Remote backend (port 8000)
  </Step>

  <Step title="Access in Browser">
    Open your local browser to:

    ```
    http://localhost:3000
    ```

    The frontend will automatically connect to the backend at `localhost:8000`.
  </Step>
</Steps>

#### Dockerless Architecture with Port Forwarding

```mermaid theme={null}
flowchart LR
    subgraph Local_Machine [Local Machine]
        direction TB
        browser[Browser]
        browser -."User opens localhost:3000".-> local_frontend[localhost:3000]
        browser -."Frontend queries API".-> local_backend[localhost:8000]
    end
    subgraph Remote_Server [Remote Server]
        direction TB
        remote_backend[Backend:8000]
        remote_frontend[Frontend:3000]
    end
    local_backend -.SSH Tunnel.-> remote_backend
    local_frontend -.SSH Tunnel.-> remote_frontend
```

## Advanced Configurations

### Using a Different Local Port

If port 3333 (or 3000/8000) is already in use locally, choose different ports:

```bash theme={null}
# Docker Compose - use port 4000 locally
ssh -N -L 4000:localhost:80 unmute-box
# Then access at http://localhost:4000

# Dockerless - use ports 4000 and 4001
ssh -N -L 4000:localhost:3000 -L 4001:localhost:8000 unmute-box
# Then access at http://localhost:4000
```

<Warning>
  For Dockerless, you'll need to update the frontend configuration to point to the correct backend port if you change it.
</Warning>

### SSH Config for Easier Access

Create an SSH config file at `~/.ssh/config`:

```ssh-config ~/.ssh/config theme={null}
Host unmute-box
    HostName 192.168.1.100  # Your server IP
    User yourusername
    Port 22
    
    # Docker Compose port forwarding
    LocalForward 3333 localhost:80
    
    # Uncomment for Dockerless instead:
    # LocalForward 3000 localhost:3000
    # LocalForward 8000 localhost:8000
```

Then simply run:

```bash theme={null}
ssh unmute-box
```

Ports are automatically forwarded when you connect.

### Background Port Forwarding

Run SSH tunnel in the background:

```bash theme={null}
ssh -f -N -L 3333:localhost:80 unmute-box
```

The `-f` flag moves SSH to the background after authentication.

**To stop the background tunnel:**

```bash theme={null}
# Find the SSH process
ps aux | grep "ssh.*unmute-box"

# Kill it by PID
kill <PID>
```

### Using SSH Keys

Avoid entering passwords by setting up SSH keys:

<Steps>
  <Step title="Generate SSH Key (if needed)">
    ```bash theme={null}
    ssh-keygen -t ed25519 -C "your_email@example.com"
    ```
  </Step>

  <Step title="Copy Key to Remote Server">
    ```bash theme={null}
    ssh-copy-id unmute-box
    ```
  </Step>

  <Step title="Connect Without Password">
    ```bash theme={null}
    ssh -N -L 3333:localhost:80 unmute-box
    ```

    No password prompt!
  </Step>
</Steps>

### Autossh for Persistent Tunnels

For tunnels that automatically reconnect, use `autossh`:

```bash theme={null}
# Install autossh
sudo apt install autossh  # Ubuntu/Debian
brew install autossh       # macOS

# Create persistent tunnel
autossh -M 0 -N -L 3333:localhost:80 unmute-box
```

Autossh monitors the connection and restarts it if it drops.

## Firewall Considerations

### Remote Server Firewall

SSH port forwarding works through the SSH connection, so you only need:

* **Port 22** (or your SSH port) open on the remote server

The forwarded ports (80, 3000, 8000) don't need to be publicly accessible.

### Local Firewall

No special configuration needed - you're accessing localhost.

## Troubleshooting

### Connection Refused

**Issue**: `ssh: connect to host unmute-box port 22: Connection refused`

**Solutions**:

* Verify the hostname/IP is correct
* Check if SSH is running on the remote server: `sudo systemctl status ssh`
* Ensure firewall allows SSH: `sudo ufw allow 22`

### Port Already in Use

**Issue**: `bind [127.0.0.1]:3333: Address already in use`

**Solutions**:

* Use a different local port: `-L 3334:localhost:80`
* Find what's using the port: `lsof -i :3333`
* Kill the process using the port

### Tunnel Works but Browser Shows Error

**Issue**: Tunnel is active but `localhost:3333` doesn't load

**Solutions**:

* Verify Unmute is running on the remote server
* Check you're using the correct port (80 for Docker Compose, 3000 for Dockerless)
* Test the tunnel: `curl http://localhost:3333`

### Microphone Permission Denied

**Issue**: Browser denies microphone access even with port forwarding

**Solutions**:

* Ensure you're accessing `localhost`, not the server's IP
* Check browser permissions: Settings → Privacy → Microphone
* Try a different browser (Chrome/Firefox/Edge)

### SSH Tunnel Drops Frequently

**Solutions**:

* Use `autossh` for automatic reconnection
* Configure `ServerAliveInterval` in SSH config:
  ```ssh-config theme={null}
  Host unmute-box
      ServerAliveInterval 60
      ServerAliveCountMax 3
  ```

## Alternative: Direct HTTPS Access

If you prefer not to use SSH tunneling, set up HTTPS on your remote server:

* For production, use [Docker Swarm](/deployment/docker-swarm) which includes Let's Encrypt
* For custom setups, see [HTTPS configuration](/deployment/https)

## Performance Considerations

### Latency

SSH tunneling adds minimal latency (typically less than 10ms on good networks). The main latency comes from:

* Network distance between you and the server
* Server GPU processing time
* Internet connection quality

### Bandwidth

Unmute streams audio bidirectionally:

* **Upstream**: User audio (\~16-32 kbps)
* **Downstream**: TTS audio (\~32-64 kbps)

Total bandwidth: \~50-100 kbps, well within typical SSH capacity.

### Compression

Enable SSH compression for better performance over slow connections:

```bash theme={null}
ssh -C -N -L 3333:localhost:80 unmute-box
```

The `-C` flag enables compression.

## Security Considerations

<Warning>
  SSH tunneling is secure, but remember:

  * Don't expose SSH to the public internet without proper hardening
  * Use SSH keys instead of passwords
  * Consider restricting SSH access by IP
  * Keep SSH software updated
</Warning>

### Restricting Port Forwarding

If you're sharing SSH access, you can disable port forwarding in `/etc/ssh/sshd_config`:

```bash theme={null}
# Allow for specific users only
Match User trusted_user
    AllowTcpForwarding yes

Match User untrusted_user
    AllowTcpForwarding no
```

## Next Steps

* Set up [HTTPS](/deployment/https) for production deployments without SSH tunneling
* Learn about [Docker Compose](/deployment/docker-compose) deployment options
* Explore [Docker Swarm](/deployment/docker-swarm) for automatic HTTPS and scaling


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.