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.

It can be configured to handle:

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

server {
  
	# custom virtual host root folder
	root /var/www/mydomain.com/web/;
  
	# index file (when a folder URI is matched)
	index index.html;
 
	# server name (for virtual host resolution)
	server_name mydomain.com www.mydomain.com;
  
	# custom access and error log
	access_log /var/www/mydomain.com/log/mydomain.com.access;
	error_log /var/www/mydomain.com/log/mydomain.com.error 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
		proxy_pass http://127.0.0.1:8080;
	
		# 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 {
	proxy_pass http://127.0.0.1:9000;

	# 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 8.8.8.8;
	resolver_timeout 10s;

	# we finally tunnel the request
	proxy_pass http://your_bucket.s3.amazonaws.com/suburi;
}

Notes

Comments

comments powered by Disqus

Subscribe to my newsletter