One Nginx in front of everything: your Node app, an API, a dashboard, a game panel. Add free Let's Encrypt certificates that renew themselves, and connect WebSockets without pain.
Create an A record: app.example.com → YOUR_SERVER_IP. Wait a few minutes and check from the server:
getent hosts app.example.com
certbot will not issue a certificate until DNS points at your server.
apt update && apt install -y nginx certbot python3-certbot-nginx
ufw allow 80/tcp
ufw allow 443/tcp
cat > /etc/nginx/sites-available/app <<'EOF'
server {
listen 80;
server_name app.example.com;
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;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300s;
}
}
EOF
ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/app
rm -f /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginx
The two Upgrade lines enable WebSockets; the long read timeout keeps slow connections (SSE, long polling, game panels) from being cut at 60 seconds. Replace 127.0.0.1:3000 with whatever port your app listens on.
certbot --nginx -d app.example.com --redirect -m [email protected] --agree-tos
certbot edits the config, adds the 443 block, installs a renewal timer and sets HTTP → HTTPS redirect. Verify renewal works:
certbot renew --dry-run
systemctl list-timers | grep certbot
Another app on port 3001? Copy the server block, change server_name and proxy_pass, run certbot again. One Nginx can hold dozens of sites — a €6.5 server handles them easily.
Prefer even less config? Caddy does HTTPS with two lines — Nginx wins when you need fine control over headers, caching and timeouts.
nginx -t
tail -f /var/log/nginx/error.log
curl -I https://app.example.com
502 means Nginx is fine but your app is down or on the wrong port. 404 with a wrong page means another site block is catching the request — check server_name.
For standard browser access — yes, you need a plan with a dedicated IPv4, because Let's Encrypt validates your domain on port 80 or 443. NAT plans with forwarded ports work for bots, tunnels and VPNs, not for public websites.
Yes, and they renew automatically every 60 days via the systemd timer certbot installs. There is no paid tier needed for a normal site.
Not UDP traffic — Nginx only speaks HTTP. Games use their own ports, open them directly in the firewall instead.
Get a server with a dedicated IPv4 — plans start at €6.5/mo.