Skip to content

Instantly share code, notes, and snippets.

@Gargron
Last active April 21, 2022 12:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gargron/40afa9dc37629dfc78d6656f0ca33293 to your computer and use it in GitHub Desktop.
Save Gargron/40afa9dc37629dfc78d6656f0ca33293 to your computer and use it in GitHub Desktop.
Example nginx configuration for proxying an S3 bucket through Nginx with cache and cache lock
server {
listen 443 ssl;
server_name files.example.com;
root /var/www/html;
keepalive_timeout 30;
location = / {
index index.html;
}
location / {
try_files $uri @s3;
}
set $s3_hostname "YOUR_S3_HOSTNAME";
set $s3_backend 'https://$s3_hostname';
set $s3_bucket "YOUR_BUCKET_NAME";
location @s3 {
limit_except GET {
deny all;
}
resolver 8.8.8.8;
proxy_set_header Host $s3_hostname;
proxy_set_header Connection '';
proxy_set_header Authorization '';
proxy_hide_header Set-Cookie;
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header 'Access-Control-Allow-Methods';
proxy_hide_header 'Access-Control-Allow-Headers';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-server-side-encryption;
proxy_hide_header x-amz-server-side-encryption;
proxy_hide_header x-amz-bucket-region;
proxy_hide_header x-amzn-requestid;
proxy_ignore_headers Set-Cookie;
proxy_pass $s3_backend/$s3_bucket$uri;
proxy_intercept_errors off;
proxy_cache CACHE;
proxy_cache_valid 200 48h;
proxy_cache_valid 403 15m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
expires 1y;
add_header Cache-Control public;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
add_header X-Cache-Status $upstream_cache_status;
}
# ...
}
@Gargron
Copy link
Author

Gargron commented Jul 22, 2020

Mind that I used variables (set $s3_bucket etc) to highlight where you have to put in your own details but in reality variables in nginx are not efficient so if you can you should just hardcode those details in places where those variables are used except for $s3_backend which has to be a variable because only that way nginx will perform DNS resolution on its value to get the IP of the server you're proxying to (that's what resolver is about here).

@Boulboulouboule
Copy link

It was very helpful, thanks !

I have two questions :

  • Why are you hiding headers ? (proxy_hide_header etc.)
  • I don't get the point about using variables in the proxy_pass rule to force DNS resolution. I hardcoded every variable as you suggest in your comment and everything looks fine. Is there something I'm missing ?

@Gargron
Copy link
Author

Gargron commented Apr 20, 2022

The informational headers set by S3-like services are unnecessary for general use, so we hide them.

If you hardcode the domain without the variable, it will only resolve it once at the start. That means if the upstream service updates its DNS (e.g. because the IP they are serving data from has changed) your configuration will stop working as it will continue to connect to the old IP.

@Boulboulouboule
Copy link

Okay got it now ! Thanks for the clear answer !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment