# How to setup Nginx as REALLY static-cache reverse proxy

**URL:** <https://www.ruby-forum.com/t/how-to-setup-nginx-as-really-static-cache-reverse-proxy/233296>\
**Category:** NGINX\
**Created:** [December 2, 2014, 1:04pm UTC](https://www.ruby-forum.com/t/how-to-setup-nginx-as-really-static-cache-reverse-proxy/233296 "2014-12-02T13:04:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![addis\_a](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c4cdca/32.png) [@addis\_a](https://www.ruby-forum.com/u/addis_a)\
**Post date:** [December 2, 2014, 1:04pm UTC](https://www.ruby-forum.com/t/how-to-setup-nginx-as-really-static-cache-reverse-proxy/233296/1 "2014-12-02T13:04:49Z")

</div>

Hi,

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.

Setup:

- 

```
     For example domain "domain.com"

```

- 

```
     Production public IP: 1.2.3.4,

```

- 

```
     Primary production server LAN IP (behind NAT): IP 10.0.0.1 

```

(HTTP… only Apache, without Nginx)

- 

```
     Secondary server with Nginx LAN IP (behind NAT): IP 10.0.0.2 

```

(setup as reverse proxy for 10.0.0.1 with configured Nginx cache)

Normal situation:

- 

```
     public IP is NAT-ed to 10.0.0.1

```

- 

```
     on secondary server is in hosts record "10.0.0.2 domain.com 

```

[www.domain.com](http://www.domain.com)"

- 

```
     on secondary server is crawler job, which every day crawl 

```

whole [domain.com](http://domain.com) 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 1.2.3.4 is changed from primary server IP 

```

10.0.0.1 to secondary server 10.0.0.2

- 

```
     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!

Jan

* * *

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/domain.com levels=1:2  
keys\_zone=domain\_com:32m max\_size=15G inactive=2880m loader\_files=500  
loader\_threshold=500;

server {  
listen 10.0.0.2:80;  
access\_log /var/log/nginx/domain.com.access.log main buffer=64k;  
error\_log /var/log/nginx/domain.com.error.log warn;  
root /usr/share/nginx/html;  
server\_name [www.domain.com](http://www.domain.com) [domain.com](http://domain.com);

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

location / {
  proxy_cache domain_com;
  proxy_pass http://10.0.0.1:80;

  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;
}

```

}

---

<div class="post-metadata">

**Author:** ![Jan\_RegeSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a5b964/32.png) [@Jan\_RegeSS](https://www.ruby-forum.com/u/Jan_RegeSS)\
**Post date:** [January 6, 2016, 6:56am UTC](https://www.ruby-forum.com/t/how-to-setup-nginx-as-really-static-cache-reverse-proxy/233296/2 "2016-01-06T06:56:13Z")

</div>

I’m having the same issue with cache being browser dependent. I’ve tried  
setting up a crawl job using wget --recursive with Firefox and Chrome  
headers, but that doesn’t seem to trigger server-side caching either.

If I browse the site using Firefox, then caching works for Firefox, and  
Firefox only.

If I browse the site using Chrome, then caching works for Chrome, and  
Chrome  
only.

I’d like cache to be browser agnostic.

Any ideas?

Posted at Nginx Forum:

> **[Re: How to setup Nginx as REALLY static-cache reverse proxy](https://forum.nginx.org/read.php?2,255256,263868#msg-263868)**
>
> Hi, 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...

---

<div class="post-metadata">

**Author:** ![Jan\_RegeSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a5b964/32.png) [@Jan\_RegeSS](https://www.ruby-forum.com/u/Jan_RegeSS)\
**Post date:** [January 6, 2016, 7:08am UTC](https://www.ruby-forum.com/t/how-to-setup-nginx-as-really-static-cache-reverse-proxy/233296/3 "2016-01-06T07:08:29Z")

</div>

Can you show us your config, debug logs, or any info that would help  
troubleshoot the issue? See

> **[Debugging | NGINX](https://www.nginx.com/resources/wiki/start/topics/tutorials/debugging/)**
>
> This tutorial explains how to use some of NGINX's essential debugging features.

for  
help on setting up debug logging.

---

<div class="post-metadata">

**Author:** ![Jan\_RegeSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a5b964/32.png) [@Jan\_RegeSS](https://www.ruby-forum.com/u/Jan_RegeSS)\
**Post date:** [January 6, 2016, 1:50pm UTC](https://www.ruby-forum.com/t/how-to-setup-nginx-as-really-static-cache-reverse-proxy/233296/4 "2016-01-06T13:50:22Z")

</div>

> I’m having the same issue with cache being browser dependent. I’ve tried  
> setting up a crawl job using wget --recursive with Firefox and Chrome  
> headers, but that doesn’t seem to trigger server-side caching either.
> 
> I’d like cache to be browser agnostic.
> 
> Any ideas?

It is hard to identify problems without getting a look at the  
configuration  
but for the sake of general ideas:

For one particular case of static file caching we use nginx’s  
proxy\_store  
feature (  
[Module ngx\_http\_proxy\_module](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_store) ) -  
the  
files are literally stored as is (in the same tree structure/naming) on  
the  
cache server.

The configuration is way simple:

proxy\_ignore\_client\_abort on; // optional

upstream backend {  
server 10.10.10.10;  
}

server {  
root /path;  
error\_page 404 = @store;

```
 location @store {
    internal;
    proxy_pass http://imgstore;
    proxy_store on;
 }

```

}

Obviously there are some drawbacks (or advantages in some cases) in  
caching  
this way - the expire headers (or any other headers for that matter)  
from  
the backend (or the client) have no effect on the cache server, the  
cache  
management (purging items / used space) is fully your responsibility,  
404  
(or any other non-200) responses are not cached (which might or might  
not be  
a problem).

rr

---

<div class="post-metadata">

**Author:** ![Jan\_RegeSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a5b964/32.png) [@Jan\_RegeSS](https://www.ruby-forum.com/u/Jan_RegeSS)\
**Post date:** [January 8, 2016, 2:03am UTC](https://www.ruby-forum.com/t/how-to-setup-nginx-as-really-static-cache-reverse-proxy/233296/5 "2016-01-08T02:03:31Z")

</div>

Thanks for the responses guys.

I’ve tried proxy\_store on one config, but now I’m just receiving  
time-outs  
when I block the origin server. No stale cache on error at all.

Here are two separate configs I’m using. The first one is as described  
earlier, with caching and stale cache errors working, although cache is  
browser dependent.

proxy\_cache\_path /etc/nginx/cache/abc123.org levels=1:2  
keys\_zone=abc123:64m  
inactive=10d max\_size=1000m;  
server {  
listen 443 ssl;  
server\_name [abc123.org](http://abc123.org);  
access\_log /var/log/nginx/abc123.org.access.log;  
error\_log /var/log/nginx/abc123.org.error.log;  
include ssl.conf;  
#moved from location  
proxy\_cache\_key abc123$request\_uri;  
location / {  
proxy\_cache abc123;  
#proxy\_cache\_key abc123$request\_uri;  
add\_header X-Proxy-Cache $upstream\_cache\_status;  
proxy\_pass [https://abc123.org](https://abc123.org);  
proxy\_cache\_valid 200 720m;  
proxy\_cache\_valid 301 304 302 720m;  
proxy\_cache\_use\_stale error timeout invalid\_header updating http\_500  
http\_502 http\_503 http\_504 http\_404;  
expires max;  
add\_header Cache-control “public”;  
proxy\_connect\_timeout 3s;  
proxy\_read\_timeout 3s;  
proxy\_send\_timeout 3s;  
proxy\_cache\_revalidate on;  
proxy\_cache\_min\_uses 1;  
}  
}  
server {  
listen 80;  
server\_name [abc123.org](http://abc123.org);  
return 301 https://$server\_name$request\_uri;  
}

Config with proxy\_store

proxy\_cache\_path /etc/nginx/cache/zxf123.org levels=1:2  
keys\_zone=zxf123:64m  
inactive=10d max\_size=1000m;  
server {  
listen 443 ssl;  
server\_name [zxf123.org](http://zxf123.org);  
access\_log /var/log/nginx/zxf123.org.access.log;  
error\_log /var/log/nginx/zxf123.org.error.log;  
include ssl.conf;  
#moved from location  
proxy\_cache\_key $host$request\_uri;  
location / {  
#proxy\_cache zxf123;  
proxy\_store on;  
#proxy\_cache\_key $host$request\_uri;  
add\_header X-Proxy-Cache $upstream\_cache\_status;  
proxy\_pass [https://zxf123.org](https://zxf123.org);  
proxy\_cache\_valid 200 720m;  
proxy\_cache\_valid 301 304 302 720m;  
proxy\_cache\_use\_stale error timeout invalid\_header updating http\_500  
http\_502 http\_503 http\_504 http\_404;  
expires max;  
add\_header Cache-control “public”;  
proxy\_connect\_timeout 3s;  
proxy\_read\_timeout 3s;  
proxy\_send\_timeout 3s;  
proxy\_cache\_revalidate on;  
proxy\_cache\_min\_uses 1;  
}  
}  
server {  
listen 80;  
server\_name [zxf123.org](http://zxf123.org);  
return 301 https://zxf123.org$request\_uri;  
}

Posted at Nginx Forum:

> **[Re: How to setup Nginx as REALLY static-cache reverse proxy](https://forum.nginx.org/read.php?2,255256,263893#msg-263893)**
>
> Hi, 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...
