Prerequisites
- A domain pointing to the server
- A local application listening on a known port
- Sudo access
Security note
Keep application backends bound to localhost when they do not require direct public access. Validate configuration before every reload.
Step 1
Install Nginx
Install the distribution package and verify the service state.
sudo apt update
sudo apt install nginx
sudo systemctl status nginx --no-pagerStep 2
Create a server block
Replace example.com and port 3000. Preserve client address and protocol headers for the application.
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}Step 3
Enable and validate the site
Enable the file according to your distribution layout, remove conflicting default configuration if appropriate, and test syntax before reload.
sudo nginx -t
sudo systemctl reload nginxStep 4
Allow web traffic
Open only HTTP and HTTPS in the firewall. The backend port can remain private when Nginx is the only public entry point.
sudo ufw allow 'Nginx Full'Step 5
Add HTTPS
After DNS resolves correctly, use a supported ACME client and follow its current official instructions. Confirm automatic renewal and test it without waiting for expiration.
Troubleshooting
- Nginx returns 502 Bad Gateway
- Confirm the application is running on the configured address and port, then inspect both Nginx and application logs.
- The wrong site appears
- Check server_name values, enabled site files, DNS, and the default server selection reported by nginx -T.
Frequently asked questions
Should the application listen on 0.0.0.0?
Not when only Nginx needs to reach it. Binding the backend to 127.0.0.1 reduces unnecessary exposure.