Jump to content

Problems Regarding Http Caching With A Nginx Reverse Proxy Setup


mcdado

Recommended Posts

It's a trend recently to setup your server with a combination of nginx and Apache, the former acting as a reverse proxy for the latter. As a matter of fact, installing Plesk 12 on a VPS from OVH will enable this setup as default. There are several advantages, for example nginx is way more efficient at memory management, and concurrent from clients with slow connections will use a nginx instance instead of a Apache instance (this is a bit over-simplistic, other benefits include user/group permissions playing nicely among other things).
 
Despite the advantages there are some problems, for example regarding gzip-compression and HTTP caching. With gzip for example you need to enable it and configure it for both nginx and Apache with this particular setup, because nginx will deal directly with files that it can read on the filesystem (at least this is my interpretation) and it will deal with compression itself. To enable it I used this configuration:
# https://github.com/h5bp/server-configs-nginx/blob/master/nginx.conf
# CSS and Javascript
location ~* \.(?:css|js)$ {
    expires 1w;
    add_header Cache-Control "public";
}

Now, regarding browser caching using HTTP directives like Expires and Cache-Control (something that is very important to look at because Google's PageSpeed Insights can give you a bad grade — sometimes with good reasons, some other times not IMHO). I had problems for the same reason above: nginx seems to handle files directly, so if you are referencing images with url rewrites like PrestaShop does, it goes bonkers: when enabling directives in nginx, it will try to locate the files in the filesystem, and return 404 for files that are not really there like with rewrites. It will only work for example for images that are in the theme folder or in modules' folders, because there is no rewrite on those. No bueno!

location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
  expires 1M;
  add_header Cache-Control "public";
  add_header Expires $http_expires;
}

This led me to look into how requests to Apache are handled, because of course in the .htaccess all the necessary directives for caching are there, so Apache would be behaving correctly (I suppose) but nginx does not keep the header informations. I tried in several ways to make nginx pass the caching headers from Apache, but never managed to. Here is an example configuration I tried using:

location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
  proxy_pass_header Expires;
  proxy_pass_header Cache-Control;
}

But does not have any effect. Does anybody have any successful experience configuring this setup?

Link to comment
Share on other sites

I found the problem, and it's very silly…

 

for some reason expires_module was not enabled. So Apache was never adding caching headers to responses.

I was able to figure out by adding some directives to my site Apache configuration:

LogFormat "%r"\n"Cache-Control=%{Cache-Control}o"\n"Expires=%{Expires}o" davidlog
CustomLog /var/log/apache2/david davidlog

and when requests started to come in, I could see that the responses did not have the headers specified. So I went and checked with "apache2ctl -M" which modules were enabled, and sure enough "expires_module" was not there. On my Ubuntu VPS was simply a matter of running "a2enmod expires" and, sbam! it starte working as expected!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...