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:
- ✅ Allow WebSocket upgrade requests
- ✅ Proxy WebSocket connections properly
- ✅ Keep connections alive (no timeout)
- ✅ Forward correct headers
Configuration Examples
nginx Configuration (Recommended)
# /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:8095but nothttps://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:
-
DNS resolves:
nslookup musicassistant-app.hanold.online -
HTTPS accessible:
curl -I https://musicassistant-app.hanold.online -
Certificate valid:
openssl s_client -connect musicassistant-app.hanold.online:443 -servername musicassistant-app.hanold.online -
WebSocket works:
websocat wss://musicassistant-app.hanold.online/ws
Recommended nginx Config for Your Domain
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
- Share your reverse proxy config (nginx/Caddy/etc.)
- Run diagnostic commands above
- Check reverse proxy logs for errors
- Test with curl/browser before iOS app
- If browser works but app doesn't, it's an app issue
- If browser doesn't work, it's a server/proxy issue