Nginx proxy to AWS S3 with url rewrites

ΒΆ 2017-06-07 posts nginx aws

There seems to be plenty of information on how to use Nginx to proxy content stored in an AWS S3 bucket , but it took me a long time to figure out how to also get url rewriting to work in conjunction with this.

I wanted to rewrite the $uri to allow links to omit index.html from directories and also to omit .html extensions, and came up with the following (this goes in the server block, before the location block below):

rewrite ^/somepath/(.+)\.(html|json|rss|css)$ /somepath/$1.$2 last;
rewrite ^/somepath(|/.+)/$ /somepath$1/index.html last;
rewrite ^/somepath/(.+)$ /somepath/$1.html last;

This works as follows:

  1. If $uri has a known extension, rewrite as itself and break out of the rewrite block.
  2. Add index.html to directories and break out of the rewrite block.
  3. If we've made it this far, it doesn't have an extension and isn't a directory, so assume a .html extension.

Note that the list of extensions in line 1 needs to include everything you serve from S3, otherwise a .html extension will be added and it will 404.

Once that's done, you can then pass any requests to /somepath/ through to S3 (I have the bucket permissions set to public-read, you may need to use a different proxy_pass url):

location /somepath/ {
  proxy_intercept_errors on;
  proxy_hide_header x-amz-id-2;
  proxy_hide_header x-amz-request-id;
  proxy_pass https://s3.<region>.amazonaws.com/<bucket>/;
}

When debugging, it may help to enable logging of rewites:

rewrite_log on;
error_log /var/log/nginx/<somepath>.error.log notice;