Nginx Reverse Proxy & SSL
Nginx sits in front of the Node.js app: it terminates HTTPS, serves as the public entry point, and proxies requests to port 3000.
HTTPS is not optional
Meta (WhatsApp/Messenger/Instagram) webhooks, OAuth callbacks from every social network, and payment gateway redirects all require a valid HTTPS URL. Set up SSL before configuring any integration.
1. Server block
Create /etc/nginx/sites-available/whatsmax:
server {
listen 80;
server_name chat.example.com;
# Large enough for media uploads through the app
client_max_body_size 64m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
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/streaming support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 120s;
}
}
Enable it and reload:
sudo ln -s /etc/nginx/sites-available/whatsmax /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Your app is now reachable at http://chat.example.com.
2. Free SSL with Let's Encrypt
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d chat.example.com
Certbot rewrites the server block for HTTPS and installs an auto-renewal timer. Verify renewal works:
sudo certbot renew --dry-run
3. Update your environment
Make sure .env matches the public HTTPS URL, then restart:
APP_URL=https://chat.example.com
NEXTAUTH_URL=https://chat.example.com
AUTH_TRUST_HOST=true
pm2 restart whatsmax-web
4. Test the proxy
https://chat.example.com— landing page loads with a padlock.https://chat.example.com/admin— admin login loads.- Log in — if login loops back to the login page,
NEXTAUTH_URLdoesn't match the public URL orAUTH_TRUST_HOSTis missing.
Firewall
sudo ufw allow "Nginx Full" # 80 + 443
sudo ufw allow OpenSSH
sudo ufw enable
Port 3000 stays internal — do not open it.
Apache alternative
If you must use Apache, enable mod_proxy + mod_proxy_http + mod_proxy_wstunnel and proxy / to http://127.0.0.1:3000/ with ProxyPreserveHost On. Nginx remains the recommended and tested option.