In this tutorial we're setting up Nginx as a reverse proxy for multiple applications on Debian 13. Learn domain routing, SSL setup, and production best practices.
Introduction
How to Set Up Nginx as a Reverse Proxy for Multiple Applications on Debian 13
In real-world deployments, it is common to run multiple applications on a single server. Instead of exposing each application on separate ports, we use Nginx as a reverse proxy to route incoming traffic through domains or URL paths. This allows us to manage all applications behind a single entry point while improving security, performance, and maintainability.
In this guide, we will set up Nginx on Debian 13 and configure it to route traffic to multiple backend applications. The approach we follow is suitable for both beginners and production environments.
Prerequisites
Before we begin, ensure we have the following:
- An Debian 13 on dedicated server or KVM VPS.
- Basic Linux Command Line Knowledge.
- A domain name pointing A DNS record to server IP.
Nginx Reverse Proxy Setup for Multiple Apps
Understanding the Setup
Before we begin, it is important to understand the flow. Nginx listens on standard web ports (80 and 443) and forwards incoming requests to applications running internally on different ports.
For example:
app1.example.com → Application running on port 3000
app2.example.com → Application running on port 5000
This setup allows us to:
- Serve multiple applications using clean domain names
- Avoid exposing internal ports publicly
- Manage SSL and routing centrally
Step 1: Install Nginx on Debian 13
We start by updating the system and installing Nginx.
sudo apt update && sudo apt upgrade -y
sudo apt install nginx -y
Once installed, we enable and start the service so it runs automatically.
sudo systemctl enable nginx
sudo systemctl start nginx
We can confirm that Nginx is running:
sudo systemctl status nginx
Step 2: Configure Firewall Access
If UFW is enabled, we allow web traffic so the server can accept requests.
sudo ufw allow 'Nginx Full'
sudo ufw enable
This ensures both HTTP and HTTPS traffic are permitted.
Step 3: Verify Backend Applications
Before configuring Nginx, our applications must already be running locally. For example:
- Application 1 running on localhost:3000
- Application 2 running on localhost:5000
We can quickly verify this using:
curl http://localhost:3000
curl http://localhost:5000
If these commands do not return a response, the issue must be resolved at the application level before proceeding.
Step 4: Create Nginx Configuration for Each Application
Nginx uses server block files to define routing rules. We create a separate configuration for each application.
For the first application:
sudo nano /etc/nginx/sites-available/app1
Add the following configuration:
server {
listen 80;
server_name app1.example.com;
location / {
proxy_pass http://127.0.0.1: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;
}
}
For the second application:
sudo nano /etc/nginx/sites-available/app2
Add the following configuration:
server {
listen 80;
server_name app2.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
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;
}
}
These configurations tell Nginx how to forward incoming requests to the correct backend service.
Step 5: Enable the Configurations
Once the files are created, we enable them by linking them to the active configuration directory.
sudo ln -s /etc/nginx/sites-available/app1 /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/app2 /etc/nginx/sites-enabled/
If the default configuration is not required, we can remove it:
sudo rm /etc/nginx/sites-enabled/default
Step 6: Test and Reload Nginx
Before applying changes, we always validate the configuration.
sudo nginx -t
If the test is successful, reload Nginx:
sudo systemctl reload nginx
Step 7: Configure Domain DNS
For the setup to work externally, both domains must point to the server’s IP address.
- app1.example.com → SERVER_IP
- app2.example.com → SERVER_IP
DNS propagation may take some time depending on the provider.
Step 8: Enable HTTPS with Let’s Encrypt
To secure our applications, we install Certbot and generate SSL certificates.
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d app1.example.com -d app2.example.com
To ensure certificates renew automatically:
sudo certbot renew --dry-run
Step 9: Production Enhancements
Once the basic setup is complete, we can improve performance and reliability with a few important adjustments.
Recommended proxy headers
Add these inside the location block:
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;
Timeouts for stability
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
Enable compression
Edit /etc/nginx/nginx.conf and add inside the http block:
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
Optional: Path-Based Routing
If we prefer a single domain instead of multiple subdomains, we can route based on URL paths.
server {
listen 80;
server_name example.com;
location /app1/ {
proxy_pass http://127.0.0.1:3000/;
}
location /app2/ {
proxy_pass http://127.0.0.1:5000/;
}
}
Conclusion
In this tutorial we've setup up Nginx as a reverse proxy for multiple applications on Debian 13. Using Nginx as a reverse proxy allows us to manage multiple applications efficiently behind a single server. It simplifies routing, improves security, and prepares our infrastructure for scaling in the future.
When configured properly, this setup becomes a reliable foundation for deploying modern applications in production environments.

