upstream philomena { server app:4000 fail_timeout=0; } map $uri $custom_content_type { default "text/html"; ~(.*\.png)$ "image/png"; ~(.*\.jpe?g)$ "image/jpeg"; ~(.*\.gif)$ "image/gif"; ~(.*\.svg)$ "image/svg+xml"; ~(.*\.mp4)$ "video/mp4"; ~(.*\.webm)$ "video/webm"; } lua_package_path '/etc/nginx/lua/?.lua;;'; resolver 1.1.1.1 ipv6=off; init_by_lua_block { aws_sig = require('aws-signature') function clear_request() -- Get rid of any client state that could cause -- issues for the proxied request for h, _ in pairs(ngx.req.get_headers()) do if string.lower(h) ~= 'range' then ngx.req.clear_header(h) end end ngx.req.set_uri_args({}) ngx.req.discard_body() end function sign_aws_request() -- The API token used should not allow writing, but -- sanitize this anyway to stop an upstream error if ngx.req.get_method() ~= 'GET' then ngx.status = ngx.HTTP_UNAUTHORIZED ngx.say('Unauthorized') return ngx.exit(ngx.HTTP_UNAUTHORIZED) end clear_request() aws_sig.s3_set_headers("$S3_HOST", ngx.var.uri) end } proxy_cache_path /var/www/cache levels=1:2 keys_zone=s3-cache:8m max_size=1000m inactive=600m; server { listen 80 default; listen [::]:80; root $APP_DIR/priv/static; client_max_body_size 125000000; client_body_buffer_size 128k; location ~ ^/$S3_BUCKET { internal; access_by_lua "sign_aws_request()"; proxy_pass "$S3_SCHEME://$S3_HOST:$S3_PORT"; proxy_cache s3-cache; proxy_cache_valid 1h; proxy_hide_header Content-Type; proxy_ssl_server_name on; expires max; add_header Cache-Control public; add_header Content-Type $custom_content_type; } location ~ ^/img/download/(.+)/([0-9]+).*\.([A-Za-z0-9]+)$ { rewrite ^/img/download/(.+)/([0-9]+).*\.([A-Za-z0-9]+)$ "/$S3_BUCKET/images/$1/$2/full.$3" break; access_by_lua "sign_aws_request()"; proxy_pass "$S3_SCHEME://$S3_HOST:$S3_PORT"; proxy_cache s3-cache; proxy_cache_valid 1h; proxy_hide_header Content-Type; proxy_ssl_server_name on; expires max; add_header Cache-Control public; add_header Content-Type $custom_content_type; add_header Content-Disposition "attachment"; } location ~ ^/img/view/(.+)/([0-9]+).*\.([A-Za-z0-9]+)$ { rewrite ^/img/view/(.+)/([0-9]+).*\.([A-Za-z0-9]+)$ "/$S3_BUCKET/images/$1/$2/full.$3" last; } location ~ ^/img/(.+)$ { rewrite ^/img/(.+)$ "/$S3_BUCKET/images/$1" last; } location ~ ^/spns/(.+) { rewrite ^/spns/(.+)$ "/$S3_BUCKET/adverts/$1" last; } location ~ ^/avatars/(.+) { rewrite ^/avatars/(.+)$ "/$S3_BUCKET/avatars/$1" last; } # The following two location blocks use an -img suffix to avoid # conflicting with the application routes. In production, this # is not necessary since assets will be on a distinct domain. location ~ ^/badge-img/(.+) { rewrite ^/badge-img/(.+)$ "/$S3_BUCKET/badges/$1" last; } location ~ ^/tag-img/(.+) { rewrite ^/tag-img/(.+)$ "/$S3_BUCKET/tags/$1" last; } location / { try_files $uri @proxy; } location @proxy { proxy_pass http://philomena; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; # Configuration for Phoenix WS proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }