How I Configured Nginx Reverse Proxy for My Web App
Nginx Reverse Proxy Deployment Web Server
When I deployed my web application on a server, the app was running internally on a port like 3000.
This is common for Node.js, Next.js, Express, and many backend applications. But a real user should not open a website
using a port number. Users should visit a clean domain such as example.com or www.example.com.
To solve this, I used Nginx as a reverse proxy. Nginx receives requests from the public domain and forwards them to the internal application port. This made the deployment cleaner, more professional, and easier to connect with HTTPS.
Why Reverse Proxy Is Needed
A web app running on a server usually listens on an internal port. For example, a Next.js app may run on
localhost:3000. This is fine for development or internal server communication, but it is not ideal for
public access.
A reverse proxy solves this problem by acting as a middle layer. Users send requests to the domain, Nginx receives those requests, and then Nginx forwards them to the actual app running in the background.
This setup gives several benefits:
- Users can access the app through a clean domain name.
- The internal app port does not need to be exposed directly.
- HTTPS setup becomes easier using Certbot and Nginx.
- Multiple apps can run on one server using different domains or paths.
- Nginx can handle public traffic more efficiently.
My Deployment Situation
In my setup, the application was running with PM2. PM2 kept the Node.js app alive in the background, and the app listened on an internal port. But the domain needed to point to the app without showing the port number.
The flow looked like this:
User → Domain → Nginx → Node.js/Next.js App on Port 3000
This simple flow is the basic idea behind reverse proxy deployment.
Installing Nginx
On an Ubuntu server, Nginx can be installed using the package manager:
sudo apt update
sudo apt install nginx
After installation, I checked whether Nginx was running:
sudo systemctl status nginx
If Nginx is active, it means the web server is running properly.
Basic Nginx Reverse Proxy Configuration
The main Nginx configuration idea is simple. A server block listens for requests on the domain and forwards them to the local app port.
server {
listen 80;
server_name example.com www.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
In this example, users visit example.com, and Nginx sends the request to localhost:3000.
The user never sees port 3000 in the browser.
proxy_pass value should be updated.
Testing Nginx Configuration
After writing or editing the Nginx config, I tested it before restarting Nginx:
sudo nginx -t
This command checks whether the Nginx configuration has syntax errors. It is very important because a small mistake can break the Nginx service.
If the test is successful, Nginx can be reloaded:
sudo systemctl reload nginx
Reloading is better than restarting in many cases because it applies changes without fully stopping the service.
Connecting Domain with Server
Nginx configuration alone is not enough. The domain DNS should also point to the server IP address. Usually, this is done by adding an A record in the domain DNS settings.
The A record points the domain to the public IP of the server. After DNS propagation, the domain starts reaching the server, and Nginx handles the request.
DNS changes can sometimes take time. If the domain does not work immediately, it does not always mean the configuration is wrong. It may simply need time to update.
Adding HTTPS with Certbot
After the domain and Nginx configuration were working, the next important step was HTTPS. A production website should open with a secure HTTPS connection.
Certbot can automatically configure SSL for Nginx:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
After successful SSL setup, the website starts opening with HTTPS. This improves trust, browser compatibility, and SEO.
Common Problems I Faced
While working with Nginx reverse proxy, I faced some common issues. These issues helped me understand production debugging better.
1. App was not running
Sometimes Nginx was working, but the app behind it was not running. In that case, the website showed a bad gateway error. The fix was to check PM2 status:
pm2 status
pm2 logs
2. Wrong port in proxy_pass
If the app runs on port 3000 but Nginx forwards traffic to another port, the website will not work. The port in
proxy_pass should match the actual app port.
3. Nginx config syntax error
A missing semicolon or wrong bracket can break the configuration. That is why I always use:
sudo nginx -t
4. DNS not pointing correctly
Sometimes the domain does not reach the server because DNS records are wrong or not propagated yet. Checking DNS records is important before assuming the server is broken.
5. SSL issue
Certbot needs the domain to correctly point to the server before SSL can be issued. If DNS is not correct, SSL setup may fail.
Useful Commands
These commands helped me manage Nginx:
sudo systemctl status nginx
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl restart nginx
sudo systemctl stop nginx
sudo systemctl start nginx
These commands are basic but very useful for deployment and debugging.
What I Learned
Nginx helped me understand how production web traffic works. Before using Nginx, I only thought about running the app. But after configuring reverse proxy, I understood how domain, server, internal port, HTTPS, and process manager connect together.
I also learned that deployment issues are usually connected. If the site is not opening, the problem can be in DNS, Nginx, PM2, app port, firewall, SSL, or the app itself. Debugging means checking each layer step by step.
Conclusion
Nginx reverse proxy is a very important part of production deployment. It allows a web app running on an internal port to be accessed through a clean domain name. It also works well with PM2 and Certbot to create a stable deployment setup.
For my web app deployment, Nginx made the setup more professional and production-ready. It connected the domain with the app, helped with HTTPS setup, and gave me a better understanding of how live web applications are served.