6

I would like Nginx to return actual files instead of response with Location: redirect header. I use Nginx as a reverse proxy cache: cdn.mydomain.com receives a request and contacts api.mydomain.com/files/ to fetch image files from there, but api.mydomain.com/files/ returns a blank response with Location: redirect header to AWS S3, instead of a file itself.

Thus, Nginx caches the blank redirect response. How can I make Nginx to fetch and cache the actual file from S3.

user www-data;
worker_processes 4;
pid /var/run/nginx.pid;

http {
    server_names_hash_bucket_size 64;
    proxy_redirect off;

    proxy_cache_path /var/cache/nginx levels=2:2:2 keys_zone=my-cache:8m max_size=4G inactive=600m;
    proxy_temp_path /var/cache/tmp;

    server {
        listen 80;
        server_name cdn.mydomain.com;
        server_tokens off;
        location / {
            proxy_pass http://api.mydomain.com/files/;

            proxy_cache my-cache;
            proxy_cache_valid 200 302 30d;
            expires 30d;
            add_header Pragma public;
            add_header Cache-Control "public";
        }
}
Vad
  • 4,052
  • 3
  • 29
  • 34

2 Answers2

2

I had just the same need and I couldn't find any working solution, so I combined what I have learned from Nginx mailing lists and Nginx documentation:

proxy_cache_path /tmp/docker/nginx/cache levels=1:2 keys_zone=DOCKERHUB:10m inactive=24h max_size=8g;

server {
    ...

    location /v2/ {
        proxy_pass https://registry-1.docker.io;
        proxy_cache            DOCKERHUB;
        #proxy_cache_valid      200  1d;
        #proxy_cache_use_stale  error timeout invalid_header updating
        #                       http_500 http_502 http_503 http_504;
        #proxy_cache_lock on;
        proxy_intercept_errors on;
        error_page 301 302 307 = @handle_redirect;
    }

    location @handle_redirect {
        set $saved_redirect_location '$upstream_http_location';
        proxy_pass $saved_redirect_location;
        proxy_cache            DOCKERHUB;
        #proxy_cache_valid      200  1d;
        #proxy_cache_use_stale  error timeout invalid_header updating
        #                       http_500 http_502 http_503 http_504;
        #proxy_cache_key $scheme$proxy_host$uri;
        #proxy_cache_lock on;
    }
}

P.S. I have commented out the proxy_cache options relevant to my use-case, but you may still find them useful.

Vlad Frolov
  • 7,445
  • 5
  • 33
  • 52
-1

Doing that all traffic for downloading the files will pass through the nginx.

I would recomment setting up separate DNS record for example files.mydomain.com and point it to Amazon S3 bucket. This would like its served from your domain, but all traffic would go through Amazon.

Documentation about setting up the DNS

Ahmed Al Hafoudh
  • 8,281
  • 1
  • 18
  • 34