I've been fighting with configuring Nginx as a reverse proxy. I've got most of the mechanics working, but I've been fighting for the last 3 days to control cache headers and being newbie to nginx this is driving me crazy...
It looks like I'm not getting how location block chain up.
I would really appreciate a bit of help
What I would like is simple
- all content-type
text/html
to have headerCache-Control: max-age=60, public, must-revalidate
- all css/js/images etc... to have header
Cache-Control: max-age=315360000, public
- 404 and all errors not to have cache control
Thanks for any advice on how this should be done.
here I have the proxy settings (seems to work as expected)
proxy_cache_path /tmp/example levels=1:2 keys_zone=example:100m max_size=4g inactive=60m;
proxy_temp_path /tmp/example/tmp;
server {
listen 80;
server_name example.com;
# is this realy needed?
# Perhaps it should point to an empty folder
root /var/www/vhosts/example.com/www;
location ~ /\. {
deny all;
}
location ~ /purge(/.*) {
proxy_cache_purge nx_anto "$scheme$request_method$host$1";
}
location / {
proxy_cache example;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_connect_timeout 60s;
proxy_cache_methods GET HEAD;
# don't honour cache headers from the app server
# proxy_ignore_headers Cache-Control Set-Cookie Expires Cache-Control;
proxy_cache_lock on;
# proxy_cache_min_uses 3;
# proxy_cache_valid 301 24h;
# keep objects long enough for proxy_cache_use_stale
proxy_cache_valid 200 302 1h;
# 404 errors
proxy_cache_valid any 5m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
# to pass If-Modified-Since to the origin server
# proxy_cache_revalidate on;
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 X-Forwarded-Proto $scheme;
# hide cache-related headers
proxy_hide_header X-Powered-By;
# this avoids having duplicate Vary headers sent to final client.
proxy_hide_header Vary;
# proxy_hide_header Pragma;
# proxy_hide_header Expires;
# proxy_hide_header Last-Modified;
# proxy_hide_header Cache-Control;
# proxy_hide_header Set-Cookie;
set $skip_cache 0;
# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
set $skip_cache 1;
}
# wordpress adds query strings to css and js that we want to cache
# if ($query_string != "") {
# set $skip_cache 1;
# }
# Don't cache uris containing the following segments
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
set $skip_cache 1;
}
# Don't use the cache for logged in users or recent commenters
# if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
# wordpress_[a-f0-9]+ was blocking cache on loged out users
if ($http_cookie ~* "comment_author|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $skip_cache 1;
}
proxy_cache_bypass $skip_cache;
proxy_no_cache $skip_cache;
# for debugging
add_header "X-Cache-Status" $upstream_cache_status;
add_header "X-Dummy" $sent_http_content_type;
proxy_pass http://example.com:8080;
}
}
now comes the app vhost
server {
listen 8080;
server_name example.com;
root /var/www/vhosts/example.com/www;
index index.php;
server_tokens off;
etag off;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
include fastcgi_params;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php5.6-fpm_example.sock;
access_log /var/log/nginx/phpfpmonly-access-example.log;
try_files $uri /index.php =404;
## I never got this condition to work
# if ($sent_http_content_type ~* "text/html") {
# add_header "Cache-Control" "public, must-revalidate, proxy-revalidate";
# expires 60s;
# }
}
}
now I would like to control headers for css/js etc...
location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom||zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|css|js|ico|gif|jpe?g|png|svg|eot|otf|woff|woff2|ttf|ogg) {
expires max;
add_header Cache-Control "public";
}
I've tried putting this location block in any server block (proxy or app) and never got what I wanted. Placed in the app server block this break php (returning me php source code)
You should be using fastcgi cache, not the proxy cache, unless you have a really good reason to be using a proxy cache. I have a tutorial that addresses exactly what you're trying to do, you can read it here, and it has downloadable configuration files.
You have to have mod_headers built into Nginx to control headers. My tutorial covers that.
SF prefers the answer to be in the question in case websites disappear. The website will be easier to read, and should be around for a good while. Copied below for reference.
Nginx configuration file
Here's how I built Nginx