Configure Nginx as a Reverse Proxy and API Gateway
How to use Nginx as a reverse proxy for backend services, implement load balancing, SSL termination, and rate limiting for production API gateways
Note: This guide follows English-language naming conventions and terminology standards common in international development teams. Examples use English identifiers and comments to maximize compatibility across codebases and tooling.
Configure Nginx as a Reverse Proxy and API Gateway
Nginx is a high-performance web server that excels as a reverse proxy and API gateway. It handles SSL termination, load balancing across multiple backends, path-based routing, and rate limiting — all with minimal memory overhead and predictable performance under high concurrency.
When to Use This
- You need to expose multiple backend services through a single entry point
- SSL/TLS termination should happen at the edge, not in application code
- You want to add rate limiting, caching, or request rewriting without modifying backends
Prerequisites
- Nginx 1.18+ installed
- Backend services running on known ports or hostnames
Solution
1. Basic Reverse Proxy
# /etc/nginx/sites-available/api
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
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;
}
}
2. Path-Based Routing to Multiple Services
# /etc/nginx/sites-available/gateway
server {
listen 80;
server_name gateway.example.com;
# User service
location /api/users/ {
proxy_pass http://user-service:8080/;
proxy_set_header Host $host;
}
# Order service
location /api/orders/ {
proxy_pass http://order-service:8081/;
proxy_set_header Host $host;
}
# Payment service
location /api/payments/ {
proxy_pass http://payment-service:8082/;
proxy_set_header Host $host;
}
# Static assets from CDN
location /assets/ {
proxy_pass https://cdn.example.com/;
proxy_cache_valid 200 1h;
}
}
3. Load Balancing with Health Checks
# /etc/nginx/conf.d/upstreams.conf
upstream user_service {
least_conn;
server 10.0.1.10:8080 weight=5;
server 10.0.1.11:8080 weight=5;
server 10.0.1.12:8080 backup;
keepalive 32;
}
server {
location /api/users/ {
proxy_pass http://user_service/;
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
}
}
4. Rate Limiting
# /etc/nginx/conf.d/rate-limit.conf
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_conn addr 10;
limit_req_status 429;
proxy_pass http://backend/;
}
}
5. SSL Termination with Let’s Encrypt
# /etc/nginx/sites-available/api-ssl
server {
listen 80;
server_name api.example.com;
return 301 https://$server_name$request_uri;
}
server {
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;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
}
}
How It Works
- Reverse Proxy forwards client requests to backend services
- Path Routing maps URL prefixes to different upstream services
- Load Balancing distributes traffic across healthy backend instances
- Rate Limiting prevents abuse using token bucket algorithms
- SSL Termination decrypts HTTPS traffic at the edge for backend efficiency
Production Considerations
- Enable HTTP/2 on the frontend for multiplexed connections
- Use keepalive connections to backends to reduce TCP overhead
- Implement sticky sessions only when necessary; prefer stateless design
- Monitor upstream health with active checks or passive failure detection
Common Mistakes
- Not preserving
HostandX-Forwarded-*headers, breaking backend routing - Using
ip_hashload balancing without considering NATed clients - Forgetting to increase
worker_connectionsfor high-traffic deployments
FAQ
Q: Should I use Nginx or an API gateway like Kong or Traefik? A: Nginx is sufficient for routing, SSL, and rate limiting. Use Kong or Traefik when you need plugins, service discovery, or Kubernetes-native features.
Q: How do I handle WebSocket connections through Nginx?
A: Add proxy_set_header Upgrade $http_upgrade; and proxy_set_header Connection "upgrade"; to the location block.
Q: Can Nginx cache API responses?
A: Yes. Use proxy_cache with cache keys based on URL and authorization headers. Be cautious with authenticated endpoints.