It's taken some trial and error, but I have a good setup now for a Drupal 8 site that runs on Apache behind an Nginx reverse-proxy caching server. Just sharing the basics of the recipe here (obviously this is just a portion of the config).
The connection to Apache is defined in /etc/nginx/apache_proxy.conf and the key logic is found in the location blocks that either send requests to Apache directly (using that config file or the @proxy alias) or to the caching service at @cache.
The following setup was designed to solve the following problems:
- not cache edit / translate etc node pages
- not cache admin & user pages
- pass requests to generate image styles through
# no caching for admin, user pages
location ~ /(admin|user)/ {
include /etc/nginx/apache_proxy.conf;
add_header X-Cache-Status ADMIN;
}
# no caching for editing, translating, etc
location ~ /node/[0-9]+/(edit|translations|revisions|delete)$ {
include /etc/nginx/apache_proxy.conf;
add_header X-Cache-Status ADMIN;
}
# no caching for block admin
location ~ /block/[0-9]+$ {
include /etc/nginx/apache_proxy.conf;
add_header X-Cache-Status ADMIN;
}
# explicit config for image styles
location ~ ^/sites/.*/files/styles/ {
try_files $uri @proxy;
}
# serve files directly
# then default to caching proxy
location / {
try_files $uri @cache;
}
# direct Apache connection for image style generation
location @proxy {
include /etc/nginx/apache_proxy.conf;
}
# cached Apache connection
location @cache {
include /etc/nginx/apache_proxy.conf;
# proxy cache
proxy_cache CACHE_KEY;
proxy_cache_key $scheme$host$request_uri;
proxy_cache_valid 200 301 1h;
proxy_cache_valid 404 302 3m;
proxy_ignore_headers Cache-Control Expires;
add_header X-Proxy-Cache $upstream_cache_status;
}