
Nginx Reverse Proxy with SSL for Multiple Apps
- AuthorTimothy M.
- Date
- Time18 minutes
Prerequisites
- Ubuntu 22.04 or Debian 12 server
- A domain with DNS A records pointing to your server
- At least one backend app (Node, Python, etc.)
- Sudo privileges
Step 1: Install Nginx
bash
sudo apt update
sudo apt install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx
sudo systemctl status nginx --no-pagerStep 2: Open Firewall Ports
bash
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw statusStep 3: Create Upstream Targets
Assume two local apps are listening on ports 3000 and 4000.
bash
sudo tee /etc/nginx/conf.d/upstreams.conf >/dev/null <<'EOF'
upstream app_main {
server 127.0.0.1:3000;
}
upstream app_api {
server 127.0.0.1:4000;
}
EOFStep 4: Create Site Configuration
bash
sudo tee /etc/nginx/sites-available/example.conf >/dev/null <<'EOF'
server {
listen 80;
listen [::]:80;
server_name app.example.com api.example.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
location / {
proxy_pass http://app_main;
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;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
location / {
proxy_pass http://app_api;
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;
}
}
EOFStep 5: Enable Config and Validate
bash
sudo ln -s /etc/nginx/sites-available/example.conf /etc/nginx/sites-enabled/example.conf
sudo nginx -t
sudo systemctl reload nginxStep 6: Install Certbot and Issue Certificates
bash
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d app.example.com -d api.example.com --redirect --agree-tos -m admin@example.com --no-eff-emailStep 7: Verify Auto-Renewal
bash
systemctl list-timers | grep certbot
sudo certbot renew --dry-runStep 8: Harden TLS (Optional but Recommended)
bash
sudo tee /etc/nginx/snippets/ssl-params.conf >/dev/null <<'EOF'
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
EOF"A reverse proxy is not just routing. It is your first production control point for security, observability, and reliability."



