Nginx by examples: reverse proxy

Nginx is primarily designed as a reverse proxy and can add a lot of value if placed in front of your applications:

Let’s see how we can setup a basic Java API webapp behind Nginx

server {

    # custom virtual host root folder
    root /var/www/;

    # index file (when a folder URI is matched)
    index index.html;

    # server name (for virtual host resolution)

    # custom access and error log
    access_log /var/www/;
    error_log /var/www/ error;

    # the default catchall block
    location / {
        # this will return a 403 http error code
        deny all;

    # we server some static welcome page if present on a / request
    location =/ {
        try_files /index.html =404;

    # our apis are under /api
    location /api {

        # we tunnel through to the java web app living on localhost

        # we tweak the send and receive timeout (especially if our backend can be a bit slow)
        proxy_send_timeout 600;
        proxy_read_timeout 600;

Pretty straightforward.

If we have multiple apps hosted on the same server we can simply add another location block as follows

# our documentation is dynamically generated and served by another web app
location /docs {

    # we intercept all 302 redirects to prefix all URIs with /docs/
        # after the response has been generated by the downstream server
    proxy_redirect / /docs/;

The use of proxy_redirect is quite handy when the proxied app has no knowledge of the URL its content is actually served from.

Proxying 3rd party servers #

If we need to proxy content from another server (from Amazon S3 for example) the configuration has to be extended a bit

location /docs {

    # we force http/1.1 to take advantage of keep alive sockets
    proxy_http_version 1.1;

    # we replace the host header (for correct virtual host resolution)
    proxy_set_header Host $s3_bucket;

    # we hide some S3 specific headers
    proxy_hide_header x-amz-id-2;
    proxy_hide_header x-amz-request-id;
    proxy_hide_header Set-Cookie;

        # we can discard any cookie set by Amazon
    proxy_ignore_headers "Set-Cookie";

    # we serve the nginx error pages (as opposed to the S3 ones)
    proxy_intercept_errors on;

    # We force the method to GET in the downstream server to prevent
        # POST/PUT/DELETE requests against S3 that would result in errors
    proxy_method GET;

    # we setup a DNS resolver using Google open DNS servers
    resolver_timeout 10s;

    # we finally tunnel the request

Notes #


Now read this

Premature optimization

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are... Continue →