Files
2026-03-27 09:21:41 +01:00

9.0 KiB

Reverse Proxy Configuration for Music Assistant

Common Issues with Reverse Proxy Setup

When using a reverse proxy (nginx, Caddy, Traefik, etc.), there are specific configuration requirements for Music Assistant to work properly.

Critical: WebSocket Support

Music Assistant requires WebSocket support for real-time communication. Your reverse proxy must:

  1. Allow WebSocket upgrade requests
  2. Proxy WebSocket connections properly
  3. Keep connections alive (no timeout)
  4. Forward correct headers

Configuration Examples

# /etc/nginx/sites-available/musicassistant

server {
    listen 443 ssl http2;
    server_name musicassistant-app.hanold.online;
    
    # SSL Configuration
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    
    # SSL Settings (Let's Encrypt recommended)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    
    # Timeouts (important for WebSocket)
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
    
    # Max body size (for uploads)
    client_max_body_size 100M;
    
    location / {
        # Proxy to Music Assistant
        proxy_pass http://localhost:8095;
        
        # Required headers
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # WebSocket Support (CRITICAL!)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # Disable buffering for WebSocket
        proxy_buffering off;
    }
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name musicassistant-app.hanold.online;
    return 301 https://$server_name$request_uri;
}

Caddy Configuration (Simplest)

musicassistant-app.hanold.online {
    reverse_proxy localhost:8095 {
        # Caddy handles WebSocket automatically
        # No extra config needed!
    }
}

Apache Configuration

<VirtualHost *:443>
    ServerName musicassistant-app.hanold.online
    
    SSLEngine on
    SSLCertificateFile /path/to/cert.pem
    SSLCertificateKeyFile /path/to/key.pem
    
    # Enable WebSocket
    ProxyRequests Off
    ProxyPreserveHost On
    
    # WebSocket support
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule /(.*) ws://localhost:8095/$1 [P,L]
    RewriteCond %{HTTP:Upgrade} !=websocket [NC]
    RewriteRule /(.*) http://localhost:8095/$1 [P,L]
    
    ProxyPass / http://localhost:8095/
    ProxyPassReverse / http://localhost:8095/
</VirtualHost>

Diagnostic Steps for Reverse Proxy

1. Test Reverse Proxy Directly

# Test from server itself
curl -I http://localhost:8095

# Test HTTPS endpoint
curl -I https://musicassistant-app.hanold.online

# Test WebSocket upgrade
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" \
     https://musicassistant-app.hanold.online/ws

2. Check Reverse Proxy Logs

nginx:

sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log

Caddy:

sudo journalctl -u caddy -f

Look for:

  • WebSocket upgrade requests
  • 502/504 errors (backend not responding)
  • SSL/TLS errors
  • Connection timeouts

3. Verify Music Assistant is Accessible Locally

On the server:

# Test Music Assistant directly
curl http://localhost:8095/api/auth/login

# Should return 405 Method Not Allowed (because we didn't POST)
# or 401 Unauthorized - both are GOOD (server is responding)

# Test WebSocket endpoint
websocat ws://localhost:8095/ws

4. Check Firewall

# Check if port 443 is open
sudo ufw status
sudo iptables -L -n | grep 443

# Test from outside
telnet musicassistant-app.hanold.online 443

Common Reverse Proxy Issues

Issue 1: WebSocket Upgrade Not Working

Symptoms:

  • HTTP works but WebSocket fails
  • Connection established but immediately closes
  • Error: "WebSocket upgrade failed"

Solution: Ensure these headers are set:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Issue 2: SSL Certificate Mismatch

Symptoms:

  • "Certificate not valid for domain"
  • SSL errors in browser/app

Solution:

# Verify certificate matches domain
openssl s_client -connect musicassistant-app.hanold.online:443 -servername musicassistant-app.hanold.online

# Check certificate details
echo | openssl s_client -connect musicassistant-app.hanold.online:443 2>/dev/null | openssl x509 -noout -subject -dates

Issue 3: Connection Timeout

Symptoms:

  • Connection starts but times out
  • Works for a while then disconnects

Solution: Increase timeouts in nginx:

proxy_connect_timeout 600s;
proxy_send_timeout 600s;
proxy_read_timeout 600s;

Issue 4: Port Not Specified

Symptoms:

  • Works with https://domain:8095 but not https://domain

Solution: If your reverse proxy is on port 443, users should access without port:

  • https://musicassistant-app.hanold.online
  • https://musicassistant-app.hanold.online:8095

Update app to use port 443 (default HTTPS port):

// In LoginView, change default:
@State private var serverURL = "https://"

Issue 5: Backend Not Responding

Symptoms:

  • 502 Bad Gateway
  • 504 Gateway Timeout

Solution:

# Check Music Assistant is running
systemctl status music-assistant

# Check it's listening
netstat -tlnp | grep 8095

# Check logs
journalctl -u music-assistant -f

Testing Your Setup

Step 1: Browser Test

Open in Safari/Chrome:

https://musicassistant-app.hanold.online

Should see Music Assistant web interface or API response.

Step 2: API Test

curl -X POST https://musicassistant-app.hanold.online/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"test","password":"test"}'

Should get 401 Unauthorized or valid response.

Step 3: WebSocket Test (Critical!)

# Using websocat (install: brew install websocat)
websocat wss://musicassistant-app.hanold.online/ws

Should connect (might require auth token).

Step 4: iOS App Test

If the above works, the iOS app should work too.

App Configuration for Reverse Proxy

When using a reverse proxy on standard HTTPS port (443):

User enters:

https://musicassistant-app.hanold.online

App should connect to:

  • REST API: https://musicassistant-app.hanold.online/api/auth/login
  • WebSocket: wss://musicassistant-app.hanold.online/ws

NO PORT 8095 needed! The reverse proxy handles that internally.

Debugging iOS App Connection

Add more logging to see what URL is being used:

// In MAAuthManager.login()
logger.info("Login URL: \(loginURL.absoluteString)")

// In MAWebSocketClient.performConnect()
logger.info("WebSocket URL: \(wsURL.absoluteString)")

Check Xcode console to see exact URLs being used.

Your Specific Setup

Based on your domain musicassistant-app.hanold.online, verify:

  1. DNS resolves:

    nslookup musicassistant-app.hanold.online
    
  2. HTTPS accessible:

    curl -I https://musicassistant-app.hanold.online
    
  3. Certificate valid:

    openssl s_client -connect musicassistant-app.hanold.online:443 -servername musicassistant-app.hanold.online
    
  4. WebSocket works:

    websocat wss://musicassistant-app.hanold.online/ws
    
server {
    listen 443 ssl http2;
    server_name musicassistant-app.hanold.online;
    
    # Let's Encrypt SSL
    ssl_certificate /etc/letsencrypt/live/musicassistant-app.hanold.online/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/musicassistant-app.hanold.online/privkey.pem;
    
    # Security headers
    add_header Strict-Transport-Security "max-age=31536000" always;
    
    location / {
        proxy_pass http://127.0.0.1:8095;
        proxy_http_version 1.1;
        
        # WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # Standard headers
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

server {
    listen 80;
    server_name musicassistant-app.hanold.online;
    return 301 https://$host$request_uri;
}

Next Steps

  1. Share your reverse proxy config (nginx/Caddy/etc.)
  2. Run diagnostic commands above
  3. Check reverse proxy logs for errors
  4. Test with curl/browser before iOS app
  5. If browser works but app doesn't, it's an app issue
  6. If browser doesn't work, it's a server/proxy issue