# Proxying and caching a fragile server to ensure availability

**URL:** <https://www.ruby-forum.com/t/proxying-and-caching-a-fragile-server-to-ensure-availability/236285>\
**Category:** NGINX\
**Created:** [August 22, 2013, 3:43am UTC](https://www.ruby-forum.com/t/proxying-and-caching-a-fragile-server-to-ensure-availability/236285 "2013-08-22T03:43:17Z")\
**Posts on this page:** 4\
**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:** [August 22, 2013, 3:43am UTC](https://www.ruby-forum.com/t/proxying-and-caching-a-fragile-server-to-ensure-availability/236285/1 "2013-08-22T03:43:17Z")

</div>

Hello colleagues. I’m trying to save a website hosted on a (VERY)  
low-powered server by placing a strong nginx server in front of it as a  
caching proxy.

I don’t control the website code and the rest of its configuration, so  
I’m  
not free to move it elsewhere stronger.

I’d like to have the caching proxy serve content as fresh as possible,  
regardless of the response given by the upstream. If the upstream  
doesn’t  
respond, grab whatever we have in cache and serve it.

Below is the configuration for this particular site. With this  
configuration, (and I tried taking away many of the cache busting parts  
while testing, same results), I’m getting lots of “504 Gateway Timeout”  
errors, even after successfully loading a page and just reloading it in  
the  
browser.  
Is there something in this setup that is inherently bad?  
The server is working perfectly for other sites being proxied, it  
operates  
as an “origin pull CDN” to unload static files from various Wordpress  
blogs.

Whatever you could find to help me will be very welcome.

Thanks in advance.

server {  
listen 80;  
server\_name .thissite.com;  
access\_log /var/log/nginx/thissite.access.log;  
error\_log /var/log/nginx/thissite.errors.log; # this log only lists  
“upstream timeout” errors, no further details.

proxy\_ignore\_headers X-Accel-Expires Expires Cache-Control;

# Set proxy headers for the passthrough

#proxy\_set\_header X-Real-IP $remote\_addr;  
#proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;  
proxy\_set\_header Host $host;

# Let the Set-Cookie and Cache-Control headers through.

proxy\_pass\_header Set-Cookie;  
#proxy\_pass\_header Cache-Control;  
#proxy\_pass\_header Expires;  
proxy\_pass\_header Host;

# Fallback to stale cache on certain errors.

# 503 is deliberately missing, if we’re down for maintenance

# we want the page to display.

proxy\_cache\_use\_stale error  
timeout  
invalid\_header  
updating  
http\_500  
http\_502  
http\_504  
http\_404;

# Set the proxy cache key

set $cache\_key $scheme$host$uri$is\_args$args;

#proxy\_cache start  
set $no\_cache 0;

# POST requests and urls with a query string should always go to PHP

if ($request\_method = POST) {  
set $no\_cache 1;  
}

if ($query\_string != “”) {  
set $no\_cache 1;  
}

if ($http\_cookie ~\*  
“comment\_author|wordpress\_[a-f0-9]+|wp-postpass|wordpress\_logged\_in”) {  
set $no\_cache 1;  
}

#The different cache zones reside in different filesystems. the “pages”  
zone  
is saved in RAM for fast delivery.  
location / {  
proxy\_pass [http://upstream](http://upstream);  
proxy\_cache pages;  
proxy\_cache\_key $cache\_key;  
proxy\_cache\_valid 60m; # I was hoping to have the proxy query the  
upstream once every hour for updated content.  
# 2 rules to dedicate the no caching rule for logged in users.  
proxy\_cache\_bypass $no\_cache; # Do not cache the response.  
proxy\_no\_cache $no\_cache; # Do not serve response from cache.  
add\_header X-Cache $upstream\_cache\_status;  
expires 60m;  
}

location ~\* .(png|jpg|jpeg|gif|ico|swf|flv|mov|mpg|mp3)$ {  
expires max;  
log\_not\_found off;  
proxy\_pass [http://upstream](http://upstream);  
proxy\_cache images;  
proxy\_cache\_key $cache\_key;  
proxy\_cache\_valid 365d;  
}

location ~\* .(css|js|html|htm)$ {  
expires 7d;  
log\_not\_found off;  
proxy\_pass [http://upstream](http://upstream);  
proxy\_cache scripts;  
proxy\_cache\_key $cache\_key;  
proxy\_cache\_valid 7d;  
}  
}

Posted at Nginx Forum:

> **[Proxying and caching a fragile server to ensure availability](https://forum.nginx.org/read.php?2,242106,242106#msg-242106)**
>
> Hello colleagues. I'm trying to save a website hosted on a (VERY) low-powered server by placing a strong nginx server in front of it as a caching proxy. I don't control the website code and the rest of its configuration, so I'm not free to move it...

---

<div class="post-metadata">

**Author:** ![cachito](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ce7236/32.png) [@cachito](https://www.ruby-forum.com/u/cachito)\
**Post date:** [August 22, 2013, 4:25am UTC](https://www.ruby-forum.com/t/proxying-and-caching-a-fragile-server-to-ensure-availability/236285/2 "2013-08-22T04:25:21Z")

</div>

Hello,

On Wed, Aug 21, 2013 at 9:42 PM, cachito [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> if ($http\_cookie ~\*  
> “comment\_author|wordpress\_[a-f0-9]+|wp-postpass|wordpress\_logged\_in”) {  
> set $no\_cache 1;  
> }

​​If the user sends requests using cookies from Wordpress, the cache  
won’t  
be used…  
Thus, you seem not to cache requests from Wordpress at all. That CMS  
need  
resources such as power and generates huge traffic (that needs to be  
processed aswell).  
Are you sure not all the Wordpress requests contain cookie(s)?  
​

> #The different cache zones reside in different filesystems. the “pages”  
> zone  
> is saved in RAM for fast delivery.  
> location / {  
> proxy\_pass [http://upstream](http://upstream);  
> proxy\_cache pages;  
> proxy\_cache\_key $cache\_key;  
> proxy\_cache\_valid 60m; # I was hoping to have the proxy query the  
> upstream once every hour for updated content.

​​Read the correct syntax and use of proxy\_cache\_valid.  
If no HTTP code is specified as optional parameter, it says ‘then only  
200,  
301 and 302 responses are cached’.  
​

> ```
> # 2 rules to dedicate the no caching rule for logged in users.
> proxy_cache_bypass $no_cache; # Do not cache the response.
> proxy_no_cache $no_cache; # Do not serve response from cache.
> 
> ```

​​Actually, those 2 comments are inverted: proxy\_no\_cache controls  
whether  
or not items should be written in cache and proxy\_cache\_bypass controls  
whether or not content should be read from it.  
​

> ```
> add_header X-Cache $upstream_cache_status;
> expires 60m;
> 
> ```
> 
> }

* * *

_B. R._

---

<div class="post-metadata">

**Author:** ![cachito](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ce7236/32.png) [@cachito](https://www.ruby-forum.com/u/cachito)\
**Post date:** [August 22, 2013, 4:36am UTC](https://www.ruby-forum.com/t/proxying-and-caching-a-fragile-server-to-ensure-availability/236285/3 "2013-08-22T04:36:27Z")

</div>

## B.R. Wrote:

> > 
> 
> ​​If the user sends requests using cookies from Wordpress, the cache  
> won’t  
> be used…  
> Thus, you seem not to cache requests from Wordpress at all. That CMS  
> need  
> resources such as power and generates huge traffic (that needs to be  
> processed aswell).  
> Are you sure not all the Wordpress requests contain cookie(s)?  
> ​

I’m manually deleting cookies to force caching and it isn’t happening.  
Even  
if I set $no\_cache to 0 in this particular section (or at the end of the  
if  
list) nothing happens.

> > ```
> > proxy_cache_valid 60m; # I was hoping to have the proxy query
> > 
> > ```
> 
> the
> 
> > upstream once every hour for updated content.
> 
> ​​Read the correct syntax and use of proxy\_cache\_valid.  
> If no HTTP code is specified as optional parameter, it says ‘then only  
> 200,  
> 301 and 302 responses are cached’.

This is the intended behavior. If the upstream responds something  
useful,  
cache it and serve it. Errors shouldn’t be cached, and the stale cache  
should be served for that URL.

> or not items should be written in cache and proxy\_cache\_bypass  
> controls  
> whether or not content should be read from it.

Comments aside, when $no\_cache is set to 0 it mandates that the upstream  
response should be cached and the client should be served content from  
cache, right?

Thanks B. R.

> nginx mailing list  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [mailman.nginx.org archive](http://mailman.nginx.org/mailman/listinfo/nginx)

Posted at Nginx Forum:  
[http://forum.nginx.org/read.php?2,242106,242110#msg-242110](http://forum.nginx.org/read.php?2,242106,242110#msg-242110)

---

<div class="post-metadata">

**Author:** ![cachito](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ce7236/32.png) [@cachito](https://www.ruby-forum.com/u/cachito)\
**Post date:** [August 22, 2013, 4:54am UTC](https://www.ruby-forum.com/t/proxying-and-caching-a-fragile-server-to-ensure-availability/236285/4 "2013-08-22T04:54:33Z")

</div>

Hello,

On Wed, Aug 21, 2013 at 10:35 PM, cachito [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > ```
> > > set $no_cache 1;
> > > 
> > > ```
> > 
> > Are you sure not all the Wordpress requests contain cookie(s)?  
> > ​
> 
> I’m manually deleting cookies to force caching and it isn’t happening. Even  
> if I set $no\_cache to 0 in this particular section (or at the end of the if  
> list) nothing happens.

​Is your conf really applied? Check logs on reload to be sure.  
​

> > > ```
> > > proxy_cache_key $cache_key;
> > > 
> > > ```
> 
> This is the intended behavior. If the upstream responds something useful,  
> cache it and serve it. Errors shouldn’t be cached, and the stale cache  
> should be served for that URL.

​Ok​

> > or not items should be written in cache and proxy\_cache\_bypass  
> > controls  
> > whether or not content should be read from it.
> 
> Comments aside, when $no\_cache is set to 0 it mandates that the upstream  
> response should be cached and the client should be served content from  
> cache, right?

## I unnderstood the double negation the same way as yours.

_B. R._
