How to setup Nginx as REALLY static-cache reverse proxy

Jan Regeš jan.reges at
Tue Dec 2 12:03:46 UTC 2014


i love Nginx, but i have some specific problem. Nginx cache depends also on some browser-specific factors.

In one project, we need to work with Nginx as "Static webpage mirror" for occasional outages or scheduled downtimes of primary server.

99% visitors just browsing this website and only 1% is working actively (fills some forms, etc.), so static mirror is for us important feature. Cookies can be totally ignored.


-          For example domain ""

-          Production public IP:,

-          Primary production server LAN IP (behind NAT): IP (HTTP.. only Apache, without Nginx)

-          Secondary server with Nginx LAN IP (behind NAT): IP (setup as reverse proxy for with configured Nginx cache)

Normal situation:

-          public IP is NAT-ed to

-          on secondary server is in hosts record ""

-          on secondary server is crawler job, which every day crawl whole including images, styles, etc.

-          on secondary server is Nginx configured to save cache of all requests for 48 hours and ignore all cache-control-headers from primary server

Primary server outage (expected state):

-          On router, NAT for is changed from primary server IP to secondary server

-          Secondary server properly handle all GET/HEAD request from its static cache (and in this situation, is for GET/HEAD fully independent from primary server accessibility)

What is a problem?

Nginx cache works with some other factors and "proxy_cache_key" is not so unique ID, as i expected :)

After i crawl this website by Google Chrome, for Google Chrome, cache from secondary server works great (all requests are with HIT state). But when i access to the same domain and same URL from other browser (iOS, Safari, Firefox, IE, Opera, Wget, Curl, etc.), Nginx cache show in log "MISS" for these requests and trying to load URL content from primary server (which is down, so it doesn't work).

So, this static website works partially and just for some browsers, that was close to browser/crawler, which was crawling website to load into nginx cache.

I found, that one of these factors is "Vary" header and after ignoring this header, it works better. But, there are still some other factors/header.

Could you help me with it? :)

I need to setup Nginx to be independent on browser headers and write/load cache really just for unique URL and request method.

I know - there are factors like browser capabilities to handle content encoding, etc. and Nginx need to handle it properly.

I just need to bring best efficiency of this solution to our client. For example, it's OK to have this static cache working without gzipping.

Thank you for you help!



Below is my nginx configuration:

proxy_cache_key "$scheme$request_method$host$request_uri ";
proxy_cache_min_uses     1;
proxy_cache_use_stale   error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_cache_revalidate  off;
proxy_http_version      1.1;
proxy_next_upstream     off;
proxy_cache_lock on;

proxy_cache_path /var/lib/nginx/tmp/cache/ levels=1:2 keys_zone=domain_com:32m max_size=15G inactive=2880m loader_files=500 loader_threshold=500;

server {
    access_log  /var/log/nginx/ main buffer=64k;
    error_log   /var/log/nginx/ warn;
    root        /usr/share/nginx/html;

    if ($request_method !~ ^(GET|HEAD)$ ) {
        return 503;

    location / {
      proxy_cache domain_com;

      proxy_connect_timeout 3s;
      proxy_read_timeout 3s;
      proxy_send_timeout 3s;

      proxy_cache_valid any 2880m;

      proxy_ignore_headers Set-Cookie X-Accel-Expires Expires Cache-Control Vary;

      proxy_hide_header "Cache-Control";
      proxy_hide_header "Set-Cookie";
      proxy_hide_header "Vary";

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header HTTP_REMOTE_ADDR $remote_addr;
      proxy_set_header REMOTE_ADDR $remote_addr;

      proxy_set_header Accept-Encoding ""; # Deny compression in Apache

      add_header X-Proxy-Cache $upstream_cache_status;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the nginx mailing list