Christian
Christian

Reputation: 612

Caching images on all folder levels of nginx reverse proxy

I'm trying to get my head around caching images for my open source image hosting serivce PictShare.

Pictshare has a smart query system where an uploaded image can be in a "virtual subdirectory" that changes the image. For example this is the link to the uploaded stackoverflow logo: https://www.pictshare.net/6cb55fe938.png

I can resize it to 300 width by adding /300/ to the URL before the image name: https://www.pictshare.net/300/6cb55fe938.png

Since I'm dealing with a lot of traffic lately I want my nginx proxy to be able to cache all images in from all virtual sub folders but it's not working. I've read many articles and many stackoverflow posts but no solution worked for me.

So far this my productive vhost file

proxy_cache_path /etc/nginx/cache/pictshare levels=1:2 keys_zone=pictshare:50m max_size=1000m inactive=30d;
proxy_temp_path /etc/nginx/tmp 1 2;
proxy_cache_key "$scheme$request_method$host$request_uri";

proxy_ignore_headers "Set-Cookie";
proxy_hide_header "Set-Cookie";
proxy_buffering on;

server {
...
location / {
        proxy_pass          http://otherserver/pictshare/;
        include /etc/nginx/proxy_params;

        location ~* \.(?:jpg|jpeg|gif|png|ico)$ {
          expires max;
          proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
          proxy_cache_valid 200 301 302 1y;
          proxy_cache pictshare;
          proxy_pass          http://otherserver/pictshare$request_uri;
        }

    }
}

The problem is that no files are cached and I see every image request on the proxy destination.

The only way I got it to work was by adding a special location to the host file that has caching explicitly enabled:

   location /cached {
       proxy_cache_valid 200 1y;
        proxy_cache pictshare;
        expires 1y;

        proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;

        include /etc/nginx/proxy_params;

        proxy_pass          http://otherserver/pictshare/thumbs/;
       proxy_cache_use_stale  error timeout invalid_header updating http_500 http_502 http_503 http_504;

        }

The obvious problem with this solution is that the images are only cached when the request starts with /cached eg: https://www.pictshare.net/cached/6cb55fe938.png

Adding the caching commands to the root directory is no option for me since I don't want the forms and pages to be cached, just the images

Where is my mistake?

Upvotes: 3

Views: 9039

Answers (1)

Yura
Yura

Reputation: 29

proxy_cache_path /etc/nginx/cache/pictshare levels=1:2 keys_zone=my_cache:50m max_size=3g inactive=180m;
proxy_temp_path /etc/nginx/tmp 1 2;
proxy_cache_key "$scheme$request_method$host$request_uri";

location ~* ^.+\.(jpe?g|gif|png|ico|pdf)$ {
    access_log off;
    include /etc/nginx/proxy.conf;
    proxy_pass http://backend;
    proxy_cache pictshare;
    proxy_cache_valid any 12h;
    add_header X-Proxy-Cache $upstream_cache_status;
    root /var/www/public_html/cached; }

location / {
    include /etc/nginx/proxy.conf;
    proxy_pass http://backend;
    root /var/www/public_html;
}

nginx first searches for the most specific prefix location given by literal strings regardless of the listed order. In the configuration above the only prefix location is “/” and since it matches any request it will be used as a last resort. Then nginx checks locations given by regular expression in the order listed in the configuration file. The first matching expression stops the search and nginx will use this location. If no regular expression matches a request, then nginx uses the most specific prefix location found earlier. http://nginx.org/en/docs/http/request_processing.html

Upvotes: 2

Related Questions