Configuring Nginx as a reverse proxy places a stable entrypoint in front of application servers, enabling centralized TLS termination, caching, and edge controls such as rate limiting.

A reverse proxy accepts client requests, forwards them to a defined upstream, and returns the upstream response to the client. Forwarded headers such as Host, X-Forwarded-For, and X-Forwarded-Proto carry request context so the upstream can generate correct absolute URLs, log real client identity, and enforce scheme-aware redirects.

Proxy behavior is strongly influenced by timeouts, buffering, and header trust boundaries, especially when traffic passes through additional load balancers or when the upstream uses streaming or WebSockets. Configuration changes should be syntax-tested before reload, then validated with real requests plus log review to confirm correct routing and client metadata.

Steps to configure Nginx as a reverse proxy:

  1. Confirm the upstream service responds on the backend address.
    $ curl -i http://127.0.0.1:8080/
    HTTP/1.0 200 OK
    Server: SimpleHTTP/0.6 Python/3.12.3
    Date: Tue, 30 Dec 2025 00:56:46 GMT
    Content-type: text/html
    Content-Length: 20
    Last-Modified: Mon, 29 Dec 2025 22:23:50 GMT
    
    Upstream cache demo
  2. Create /etc/nginx/conf.d/app-reverse-proxy.conf containing an upstream block with a matching server block for the proxied site.
    upstream app_backend {
        server 127.0.0.1:8080;
        keepalive 32;
    }
    
    server {
        listen 80;
        server_name example.com;
    
        location / {
            proxy_pass http://app_backend;
    
            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;
    
            proxy_redirect off;
    
            proxy_connect_timeout 5s;
            proxy_send_timeout 60s;
            proxy_read_timeout 60s;
        }
    }

    When proxying a subpath (for example, /app/), the presence of a trailing slash on proxy_pass changes upstream URI construction; keep URI mapping intentional to avoid unexpected 404s or doubled path segments.

  3. Test the Nginx configuration for syntax errors.
    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
  4. Reload the nginx service to apply the reverse proxy configuration.
    $ sudo systemctl reload nginx
  5. Check the nginx service status for an active running state.
    $ sudo systemctl status nginx
    ● nginx.service - A high performance web server and a reverse proxy server
         Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
        Drop-In: /etc/systemd/system/nginx.service.d
                 └─limits.conf
         Active: active (running) since Mon 2025-12-29 22:09:39 UTC; 2h 24min ago
    ##### snipped #####
  6. Request headers through Nginx to confirm proxying works end-to-end.
    $ curl -I http://127.0.0.1/
    HTTP/1.1 200 OK
    Server: nginx
    Date: Tue, 30 Dec 2025 00:56:46 GMT
    Content-Type: text/html
    Content-Length: 20
    Connection: keep-alive
    Keep-Alive: timeout=15
    Vary: Accept-Encoding
    Last-Modified: Mon, 29 Dec 2025 22:23:50 GMT
    X-Cache-Status: STALE
  7. Inspect the Nginx access log entry for the proxied request.
    $ sudo tail -n 2 /var/log/nginx/access.log
    127.0.0.1 - [30/Dec/2025:00:56:46 +0000] "HEAD / HTTP/1.1" 200 0 0.003