Skip to content

Latest commit

 

History

History
400 lines (272 loc) · 11.3 KB

File metadata and controls

400 lines (272 loc) · 11.3 KB

NGINX Reverse Proxy Setup for OpenTranscribe

This guide explains how to set up NGINX with SSL/TLS for OpenTranscribe, enabling:

  • Browser microphone recording (required for HTTPS - browsers block mic access over HTTP)
  • Secure access from any device on your network
  • Production deployments with custom domains

PKI / Mutual TLS (mTLS) Authentication

NGINX is required for PKI certificate-based authentication. The --with-pki flag loads docker-compose.pki.yml which configures NGINX to verify client certificates before forwarding requests to the backend.

# Start with PKI (production only — dev mode cannot handle mTLS)
./opentr.sh start prod --build --with-pki

# Access at https://localhost:5182
# Requires a valid client certificate (.p12 file)

Client certificates are generated by scripts/pki/ and stored in scripts/pki/test-certs/clients/. For production deployments, replace test certificates with your organization's CA-signed certificates.

Note: PKI mode only works with the prod environment overlay. The dev Vite server cannot perform mTLS handshakes.


Why HTTPS is Required

Modern browsers enforce strict security policies. The getUserMedia() API (used for microphone access) only works in:

  1. localhost connections (development exception)
  2. HTTPS connections (production requirement)

If you try to use microphone recording over HTTP from another device or IP address, browsers will block it. This is documented in GitHub Issue #72.


Quick Start (Homelab/Local Network)

For homelabs and small businesses, self-signed certificates are the fastest way to get HTTPS working.

Step 1: Generate SSL Certificates

# Navigate to OpenTranscribe directory
cd /path/to/OpenTranscribe

# Generate certificates with auto-detected IP addresses
./scripts/generate-ssl-cert.sh opentranscribe.local --auto-ip

# Or specify IP addresses manually
./scripts/generate-ssl-cert.sh opentranscribe.local --ip 192.168.1.100 --ip 10.0.0.50

This creates:

  • nginx/ssl/server.crt - SSL certificate
  • nginx/ssl/server.key - Private key

Step 2: Configure Environment

Edit your .env file and add/uncomment:

NGINX_SERVER_NAME=opentranscribe.local

Step 3: Configure DNS (Choose One)

Option A: Router DNS (Recommended)

Add a DNS entry in your router pointing opentranscribe.local to your server's IP address.

Option B: Local Hosts File

On each client device, add to /etc/hosts (Linux/Mac) or C:\Windows\System32\drivers\etc\hosts (Windows):

192.168.1.100  opentranscribe.local

Replace 192.168.1.100 with your server's actual IP address.

Multi-Service Homelab Setup

If you run multiple services on the same server, you can add multiple hostnames pointing to the same IP:

192.168.1.100  opentranscribe.local
192.168.1.100  nextcloud.local
192.168.1.100  jellyfin.local
192.168.1.100  homeassistant.local

Each service's NGINX/reverse proxy uses the Host header to route traffic correctly. This is a standard homelab configuration that works reliably.

Pi-hole / AdGuard Home / Local DNS Server

If you use a local DNS server (Pi-hole, AdGuard Home, Unbound, etc.), add an A record:

  • Domain: opentranscribe.local
  • IP Address: Your server's IP (e.g., 192.168.1.100)

Step 4: Start OpenTranscribe

./opentr.sh start dev

The script automatically detects NGINX_SERVER_NAME and includes the NGINX overlay.

Step 5: Trust the Certificate

On each device that will access OpenTranscribe, you need to trust the self-signed certificate.

Windows

  1. Copy nginx/ssl/server.crt to the client device
  2. Double-click the .crt file
  3. Click Install CertificateLocal Machine
  4. Select Place all certificates in the following store
  5. Browse and select Trusted Root Certification Authorities
  6. Complete the wizard and restart your browser

macOS

  1. Copy nginx/ssl/server.crt to the Mac
  2. Double-click to open in Keychain Access
  3. Find the certificate in the list, double-click it
  4. Expand Trust section
  5. Set When using this certificate to Always Trust
  6. Close the window and enter your password to confirm

Linux (Chrome/Chromium)

  1. Open Chrome and go to chrome://settings/certificates
  2. Click Authorities tab → Import
  3. Select nginx/ssl/server.crt
  4. Check Trust this certificate for identifying websites
  5. Click OK and restart Chrome

Linux (Firefox)

  1. Open Firefox and go to about:preferences#privacy
  2. Scroll to CertificatesView Certificates
  3. Click Authorities tab → Import
  4. Select nginx/ssl/server.crt
  5. Check Trust this CA to identify websites
  6. Click OK and restart Firefox

iOS

  1. Email or AirDrop server.crt to your iOS device
  2. Open the file → "Profile Downloaded" notification appears
  3. Go to SettingsGeneralVPN & Device Management
  4. Tap the downloaded profile and install it
  5. Go to SettingsGeneralAboutCertificate Trust Settings
  6. Enable full trust for the OpenTranscribe certificate

Android

  1. Copy server.crt to your Android device
  2. Go to SettingsSecurityEncryption & credentials
  3. Tap Install a certificateCA certificate
  4. Select the .crt file and confirm installation

Step 6: Access OpenTranscribe

Open your browser and go to:

https://opentranscribe.local

You can now use microphone recording from any device on your network!


Production Setup (Let's Encrypt)

For production deployments with a public domain, use Let's Encrypt for free, trusted certificates.

Prerequisites

  • A domain name pointing to your server (e.g., transcribe.example.com)
  • Ports 80 and 443 accessible from the internet

Step 1: Install Certbot

# Ubuntu/Debian
sudo apt install certbot

# CentOS/RHEL
sudo dnf install certbot

# macOS
brew install certbot

Step 2: Generate Certificates

Stop OpenTranscribe if running:

./opentr.sh stop

Generate certificates (standalone mode):

sudo certbot certonly --standalone -d transcribe.example.com

Or with DNS validation (if ports 80/443 aren't available):

sudo certbot certonly --manual --preferred-challenges dns -d transcribe.example.com

Step 3: Link Certificates

# Create nginx/ssl directory
mkdir -p nginx/ssl

# Link Let's Encrypt certificates
sudo ln -sf /etc/letsencrypt/live/transcribe.example.com/fullchain.pem nginx/ssl/server.crt
sudo ln -sf /etc/letsencrypt/live/transcribe.example.com/privkey.pem nginx/ssl/server.key

# Fix permissions for Docker
sudo chmod 644 /etc/letsencrypt/live/transcribe.example.com/fullchain.pem
sudo chmod 600 /etc/letsencrypt/live/transcribe.example.com/privkey.pem

Step 4: Configure Environment

Edit .env:

NGINX_SERVER_NAME=transcribe.example.com
NGINX_CERT_FILE=/etc/letsencrypt/live/transcribe.example.com/fullchain.pem
NGINX_CERT_KEY=/etc/letsencrypt/live/transcribe.example.com/privkey.pem

Step 5: Set Up Auto-Renewal

# Test renewal
sudo certbot renew --dry-run

# Add to crontab for automatic renewal
echo "0 0 1 * * certbot renew --quiet && docker compose restart nginx" | sudo tee -a /etc/crontab

Step 6: Start OpenTranscribe

./opentr.sh start prod

Configuration Reference

Environment Variables

Variable Default Description
NGINX_SERVER_NAME (none) Hostname for NGINX. Setting this enables the NGINX overlay.
NGINX_HTTP_PORT 80 HTTP port (redirects to HTTPS)
NGINX_HTTPS_PORT 443 HTTPS port
NGINX_CERT_FILE ./nginx/ssl/server.crt Path to SSL certificate
NGINX_CERT_KEY ./nginx/ssl/server.key Path to SSL private key

File Structure

OpenTranscribe/
├── docker-compose.nginx.yml    # NGINX service definition
├── nginx/
│   ├── site.conf.template      # NGINX configuration template
│   └── ssl/
│       ├── server.crt          # SSL certificate
│       └── server.key          # SSL private key
└── scripts/
    └── generate-ssl-cert.sh    # Certificate generation script

NGINX Routes

All services are accessed through a single HTTPS port when NGINX is active, providing unified access and eliminating the need to expose multiple ports.

Path Destination Description
/ Frontend (port 8080) Svelte SPA
/docs/ Docs (port 8080) Embedded documentation site
/api/ws Backend WebSocket Real-time notifications
/api/ Backend REST API All API endpoints
/flower/ Flower (port 5555) Celery task monitoring dashboard
/minio/ MinIO Console (port 9001) S3 storage management
/s3/ MinIO API (port 9000) Direct S3 operations

The Flower dashboard (/flower/) is proxied through NGINX, so task monitoring is available at the same HTTPS address as the application without exposing port 5555 separately.


Troubleshooting

"SSL certificates not found" Error

The script checks for certificates before starting. Generate them first:

./scripts/generate-ssl-cert.sh your-hostname.local --auto-ip

Browser Shows Security Warning

This is expected with self-signed certificates. You have two options:

  1. Trust the certificate on each device (recommended for homelab)
  2. Use Let's Encrypt for publicly trusted certificates (recommended for production)

"Connection Refused" on Port 443

Check if NGINX container is running:

docker compose ps nginx
docker compose logs nginx

Microphone Still Not Working

  1. Verify you're using HTTPS (not HTTP)
  2. Check browser console for errors
  3. Ensure the certificate is trusted on the device
  4. Try in an incognito/private window

Certificate Expired

For self-signed certificates:

./scripts/generate-ssl-cert.sh your-hostname.local --auto-ip
./opentr.sh restart-all

For Let's Encrypt:

sudo certbot renew
docker compose restart nginx

Advanced: Custom NGINX Configuration

To customize the NGINX configuration:

  1. Edit nginx/site.conf.template
  2. Restart NGINX: docker compose restart nginx

Common customizations:

  • Add HTTP Basic Authentication for Flower/MinIO
  • Adjust client body size limits
  • Add custom headers
  • Configure rate limiting

Example: Adding Basic Auth for Flower

location /flower/ {
    proxy_pass http://flower:5555/flower/;
    auth_basic "Flower Dashboard";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

Security Considerations

Self-Signed Certificates

  • Suitable for: Homelab, internal networks, development
  • Not suitable for: Public-facing production deployments
  • Warning: Users will see browser security warnings until they trust the certificate

Let's Encrypt Certificates

  • Suitable for: Production deployments with public domains
  • Benefits: Free, automatically trusted by all browsers
  • Requirement: Domain must be publicly accessible for validation

Certificate Best Practices

  1. Keep private keys secure (never commit to git)
  2. Use strong key sizes (2048-bit minimum, 4096-bit recommended)
  3. Renew certificates before expiration
  4. Monitor certificate expiration dates