Skip to main content
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.
Port forwarding makes the remote server appear as localhost to your browser, which allows microphone access without HTTPS.

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.
1

Start SSH Tunnel

Forward port 80 from the remote server to a local port (e.g., 3333):
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
If successful, this command produces no output and keeps running. Don’t close the terminal.
2

Access in Browser

Open your local browser to:
http://localhost:3333
The browser treats this as localhost and allows microphone access.

Docker Compose Architecture with Port Forwarding

For Dockerless

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

Start SSH Tunnel with Multiple Ports

Forward both ports in a single SSH command:
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)
2

Access in Browser

Open your local browser to:
http://localhost:3000
The frontend will automatically connect to the backend at localhost:8000.

Dockerless Architecture with Port Forwarding

Advanced Configurations

Using a Different Local Port

If port 3333 (or 3000/8000) is already in use locally, choose different ports:
# 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
For Dockerless, you’ll need to update the frontend configuration to point to the correct backend port if you change it.

SSH Config for Easier Access

Create an SSH config file at ~/.ssh/config:
~/.ssh/config
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:
ssh unmute-box
Ports are automatically forwarded when you connect.

Background Port Forwarding

Run SSH tunnel in the background:
ssh -f -N -L 3333:localhost:80 unmute-box
The -f flag moves SSH to the background after authentication. To stop the background tunnel:
# 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:
1

Generate SSH Key (if needed)

ssh-keygen -t ed25519 -C "[email protected]"
2

Copy Key to Remote Server

ssh-copy-id unmute-box
3

Connect Without Password

ssh -N -L 3333:localhost:80 unmute-box
No password prompt!

Autossh for Persistent Tunnels

For tunnels that automatically reconnect, use autossh:
# 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:
    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:

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:
ssh -C -N -L 3333:localhost:80 unmute-box
The -C flag enables compression.

Security Considerations

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

Restricting Port Forwarding

If you’re sharing SSH access, you can disable port forwarding in /etc/ssh/sshd_config:
# Allow for specific users only
Match User trusted_user
    AllowTcpForwarding yes

Match User untrusted_user
    AllowTcpForwarding no

Next Steps

  • Set up HTTPS for production deployments without SSH tunneling
  • Learn about Docker Compose deployment options
  • Explore Docker Swarm for automatic HTTPS and scaling

Build docs developers (and LLMs) love