
Learn how to route applications using URL paths like /api and /app with Nginx reverse proxy. Step-by-step guide covering configuration, headers, SSL, and production-ready setup.
Introduction
Routing applications using URL paths is a practical and widely adopted approach for serving multiple services under a single domain. Instead of managing separate domains or ports, we can configure Nginx to direct traffic based on request paths such as /api or /app.
This method is commonly used in modern architectures where APIs, frontend applications, and internal services operate independently but need to be accessed through a unified entry point.
Prerequisites
Before configuring Nginx, we should ensure that the environment is properly prepared. This avoids unnecessary troubleshooting later.
We need:
- A Linux server dedicated server or KVM VPS.
- Nginx installed and running
- Backend services already running: API service on 127.0.0.1:5000 and Application service on 127.0.0.1:3000
Learn how to route applications using URL paths like /api and /app with Nginx reverse proxy.
To install and start Nginx:
sudo apt update
sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
Understanding How Path-Based Routing Works
When a request reaches Nginx, it evaluates the URL path and decides where to send it. This decision is controlled using location blocks.
For example:
- Requests starting with
/apiare forwarded to the backend API - Requests starting with
/appare routed to the frontend application - Requests to
/can serve a default response or landing page
This approach allows us to keep everything under one domain while maintaining clear separation between services.
Creating the Nginx Configuration
We begin by creating a new server block configuration file:
sudo nano /etc/nginx/sites-available/path-routing
Add the following configuration:
server {
listen 80;
server_name example.com;
location / {
return 200 "Service Running";
}
location /api/ {
proxy_pass http://127.0.0.1:5000/;
}
location /app/ {
proxy_pass http://127.0.0.1:3000/;
}
}
Once the file is saved, enable it and reload Nginx:
sudo ln -s /etc/nginx/sites-available/path-routing /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
At this stage, Nginx is already routing traffic, but the configuration is still minimal. We now refine it for reliability and production use.
Handling Request Paths Correctly
One important detail in path-based routing is how Nginx handles trailing slashes in proxy_pass.
When we define:
location /api/ {
proxy_pass http://127.0.0.1:5000/;
}
Nginx removes the /api/ prefix before forwarding the request. This ensures that a request like /api/users becomes /users on the backend service.
If the trailing slash is omitted, the full path may be forwarded incorrectly, leading to unexpected routing issues. Keeping the trailing slash ensures predictable behavior.
Adding Required Proxy Headers
For backend applications to function correctly, especially in production, it is important to pass certain headers. These headers allow applications to detect the original client IP, protocol, and host.
Update the configuration as follows:
location /api/ {
proxy_pass http://127.0.0.1:5000/;
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;
}
Apply the same headers to the /app/ location. This ensures consistent behavior across services.
Supporting WebSocket Connections
If the frontend application uses WebSockets, we need to allow protocol upgrades. Without this, real-time features may not function correctly.
Add the following inside the /app/ block:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
Improving URL Consistency
To maintain a clean user experience, we should ensure consistent URL behavior. Requests to /api and /api/ should not behave differently.
We can enforce this using redirects:
location = /api {
return 301 /api/;
}
location = /app {
return 301 /app/;
}
This keeps routing predictable and avoids duplicate paths.
Advanced Routing: Removing Path Prefix
In some cases, backend applications expect requests without a prefix like /api. If needed, we can rewrite the URL before forwarding it.
location /api/ {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://127.0.0.1:5000;
}
With this configuration, /api/users will be sent to the backend as /users.
Performance and Stability Enhancements
For production environments, we should include basic timeout and compression settings to improve performance and reliability.
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
Enable compression:
gzip on;
gzip_types text/plain application/json application/javascript text/css;
These adjustments help optimize response times and resource usage.
Securing with SSL (HTTPS)
Serving applications over HTTPS is essential for modern deployments. We can configure SSL using Certbot.
Install Certbot:
sudo apt install certbot python3-certbot-nginx -y
Generate and configure SSL:
sudo certbot --nginx -d example.com
Enable automatic renewal:
sudo systemctl enable certbot.timer
Final Production Configuration
A refined configuration combining all improvements would look like this:
server {
listen 80;
server_name example.com;
location = /api {
return 301 /api/;
}
location = /app {
return 301 /app/;
}
location /api/ {
proxy_pass http://127.0.0.1:5000/;
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_connect_timeout 5s;
proxy_read_timeout 60s;
}
location /app/ {
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;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / {
return 200 "Service Running";
}
}
Testing the Setup
After reloading Nginx, we can verify routing by accessing:
http://example.com/api
http://example.com/app
We can also use curl:
curl http://example.com/api
curl http://example.com/app
If both endpoints respond correctly, the routing is functioning as expected.
Summary
Path-based routing with Nginx provides a clean and scalable way to manage multiple services behind a single domain. With proper configuration, it allows us to maintain clarity in architecture while ensuring performance, security, and flexibility.
This setup is well-suited for modern applications where APIs and frontend services evolve independently but are delivered as a unified platform.