Skip to main content
HTTPS is essential for production Unmute deployments because browsers require a secure connection (HTTPS) or localhost to grant microphone access. This guide explains how to add HTTPS support to your Unmute deployment.

Why HTTPS?

Modern browsers enforce strict security policies:
  • Microphone access requires either:
    • HTTPS connection with valid certificate, OR
    • Localhost connection (any protocol)
  • WebSocket connections for real-time audio work better over HTTPS
HTTP deployments (without localhost) will be blocked by browser security policies from accessing the microphone.
The easiest way to get HTTPS is to use the Docker Swarm deployment, which includes:
  • Automatic HTTPS via Let’s Encrypt
  • Certificate renewal handled automatically
  • Traefik reverse proxy configured for HTTPS
  • HTTP to HTTPS redirect
From swarm-deploy.yml:
swarm-deploy.yml
Services automatically get HTTPS:
swarm-deploy.yml
If you’re using Docker Swarm, HTTPS is already configured. No additional setup needed.

Manual HTTPS Setup

For Docker Compose or Dockerless deployments, you’ll need to add HTTPS support manually.

Prerequisites

  • Domain name pointing to your server’s public IP
  • Ports 80 and 443 open in your firewall
  • Public IP address (Let’s Encrypt needs to verify domain ownership)

Option 1: Add HTTPS to Docker Compose

Modify your docker-compose.yml to enable HTTPS with Let’s Encrypt.
1

Update Traefik Configuration

Edit the traefik service in docker-compose.yml:
docker-compose.yml
2

Update Service Labels

Update frontend and backend services to use HTTPS:
docker-compose.yml
3

Add Volume for Certificates

Add the letsencrypt volume at the end of docker-compose.yml:
docker-compose.yml
4

Deploy with HTTPS

Access your deployment at https://unmute.example.com
Let’s Encrypt certificates are valid for 90 days. Traefik automatically renews them before expiration.

Option 2: Nginx Reverse Proxy

Use Nginx as a reverse proxy with Let’s Encrypt certificates.
1

Install Certbot

2

Obtain Certificate

Certificates will be saved to /etc/letsencrypt/live/unmute.example.com/
3

Configure Nginx

Create /etc/nginx/sites-available/unmute:
/etc/nginx/sites-available/unmute
4

Enable and Restart Nginx

5

Set Up Auto-Renewal

Certbot installs a cron job automatically, but verify:

Option 3: Caddy (Automatic HTTPS)

Caddy is the simplest option - it automatically obtains and renews certificates.
1

Install Caddy

2

Configure Caddyfile

Edit /etc/caddy/Caddyfile:
/etc/caddy/Caddyfile
That’s it! Caddy automatically:
  • Obtains Let’s Encrypt certificate
  • Configures HTTPS
  • Redirects HTTP to HTTPS
  • Renews certificates
3

Restart Caddy

Caddy is the easiest option for automatic HTTPS. No certificate management needed.

Dockerless HTTPS Setup

For Dockerless deployments, you need to configure the frontend and backend separately.

Option: Nginx for Dockerless

/etc/nginx/sites-available/unmute

Testing HTTPS Configuration

1

Verify Certificate

Should show HTTP/2 200 or HTTP/1.1 200
2

Test SSL Configuration

Use SSL Labs to check your configuration:
Aim for an A or A+ rating.
3

Verify Microphone Access

Open https://unmute.example.com in your browser and test that:
  • Page loads correctly
  • No certificate warnings
  • Microphone permission prompt appears

Troubleshooting

Certificate Not Issued

Issue: Let’s Encrypt fails to issue certificate Solutions:
  • Verify domain points to your server: nslookup unmute.example.com
  • Check ports 80 and 443 are open: sudo ufw status
  • Ensure no other service is using port 80/443
  • Check Let’s Encrypt logs: sudo journalctl -u certbot

Mixed Content Errors

Issue: Browser shows mixed content warnings Solution: Ensure all resources (API calls, WebSockets) use HTTPS URLs, not HTTP.

WebSocket Connection Fails

Issue: WebSocket connections fail over HTTPS Solutions:
  • Verify proxy passes Upgrade header:
  • Check for timeout settings - WebSocket connections are long-lived
  • Test WebSocket directly: wscat -c wss://unmute.example.com/api/ws

Certificate Renewal Fails

Issue: Certificate expired or auto-renewal failed Solutions:
  • Test renewal: sudo certbot renew --dry-run
  • Check renewal cron job: sudo systemctl status certbot.timer
  • Manually renew: sudo certbot renew
  • Restart web server after renewal

Security Best Practices

Follow these security practices for production deployments:

Strong SSL Configuration

Use modern TLS versions and ciphers:

HSTS (HTTP Strict Transport Security)

Force browsers to always use HTTPS:

Certificate Monitoring

Set up monitoring to alert before certificate expiration:

Alternative: SSH Tunneling

If setting up HTTPS is too complex, consider using SSH port forwarding instead:
  • No domain name required
  • No certificate management
  • Works immediately
  • Suitable for personal/development use
HTTPS is recommended for production, but SSH tunneling is easier for testing.

Next Steps