Skip to main content
Advertisement

Upstream and Reverse Proxy Basics

Nginx's reverse proxy feature is the core mechanism for forwarding client requests to backend servers like Tomcat. Correctly configuring proxy_pass, header forwarding, buffering, and timeouts is essential for a stable proxy setup.


Reverse Proxy Concept

A reverse proxy sits between clients and backend servers, relaying requests. Clients connect only to Nginx and are unaware of the backend servers (Tomcat, etc.).

[Client]
│ GET /api/products HTTP/1.1
│ Host: example.com

[Nginx: Reverse Proxy]
│ GET /api/products HTTP/1.1
│ Host: example.com
│ X-Real-IP: client IP

[Tomcat: Backend Server]

└─ Response → Nginx → Client

Basic proxy_pass Configuration

server {
listen 80;
server_name example.com;

location /api/ {
proxy_pass http://127.0.0.1:8080;
}
}

URI Handling Difference in proxy_pass

# Case 1: No URI — location path forwarded as-is
location /api/ {
proxy_pass http://127.0.0.1:8080;
}
# GET /api/users → Backend: GET /api/users

# Case 2: URI with trailing slash — location path replaced by /
location /api/ {
proxy_pass http://127.0.0.1:8080/;
}
# GET /api/users → Backend: GET /users

# Case 3: URI with path — location path replaced by that path
location /api/ {
proxy_pass http://127.0.0.1:8080/app/;
}
# GET /api/users → Backend: GET /app/users

Header Forwarding

Nginx strips some headers by default when forwarding requests. Add headers so the backend knows the real client IP, original domain, etc.

location / {
proxy_pass http://127.0.0.1:8080;

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 X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}

upstream Block — Backend Server Group

Use an upstream block to manage multiple backend servers or reference them by name.

http {
upstream tomcat_backend {
server 127.0.0.1:8080;
}

server {
location /api/ {
proxy_pass http://tomcat_backend;
}
}
}

Shared proxy params file

# /etc/nginx/conf.d/proxy-params.conf
proxy_http_version 1.1;
proxy_set_header Connection "";
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;

# Use with include:
location / {
proxy_pass http://tomcat_backend;
include /etc/nginx/conf.d/proxy-params.conf;
}

Buffer Settings

Nginx buffers backend responses before delivering to clients. Incorrect buffer settings waste memory or degrade performance.

location / {
proxy_pass http://tomcat_backend;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
proxy_max_temp_file_size 1024m;
}

Streaming Responses (SSE, WebSocket)

Disable buffering for streaming or real-time responses:

# Server-Sent Events (SSE)
location /api/stream {
proxy_pass http://tomcat_backend;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
add_header X-Accel-Buffering no;
}

# WebSocket
location /ws/ {
proxy_pass http://tomcat_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}

Timeout Settings

location / {
proxy_pass http://tomcat_backend;
proxy_connect_timeout 10s; # Max wait for TCP connection to backend
proxy_send_timeout 60s; # Max wait for completing request transmission
proxy_read_timeout 60s; # Max wait for reading backend response
}

HTTP Version and Keep-Alive

Keeping HTTP/1.1 Keep-Alive between Nginx and backend reuses TCP connections, improving performance.

upstream tomcat_backend {
server 127.0.0.1:8080;
keepalive 32; # Keep up to 32 idle Keep-Alive connections
}

location /api/ {
proxy_pass http://tomcat_backend;
proxy_http_version 1.1;
proxy_set_header Connection ""; # Remove Connection: close header
}

Error Handling and Backup Servers

upstream tomcat_backend {
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8081 backup; # Used when main server is down
}

server {
location / {
proxy_pass http://tomcat_backend;
proxy_next_upstream error timeout http_502 http_503;
proxy_intercept_errors on;
error_page 502 503 504 /maintenance.html;
}
}

Summary

SettingDirectiveKey Point
Request forwardingproxy_passURI inclusion changes path handling
Header forwardingproxy_set_headerHost, X-Real-IP, X-Forwarded-For required
Bufferingproxy_bufferingOff for streaming, on for normal responses
Timeoutproxy_read_timeoutAdjust for slow APIs
Keep-Alivekeepalive + HTTP/1.1TCP reuse for performance gain
Advertisement