How to Set Up Nginx Reverse Proxy Caching
Updated
A reverse proxy cache sits between visitors and your app. The first visitor to ask for a page gets it from your app, and Nginx keeps a copy. Everyone after them gets the copy, so pages load faster and your app does less work. This guide puts Nginx in front of an app running on port 3000, on Ubuntu or Debian.
1. Install Nginx
sudo apt update && sudo apt install nginxOn Rocky Linux, AlmaLinux or Fedora, use sudo dnf install nginx.
2. Create a cache
Add this line inside the http block of /etc/nginx/nginx.conf. It keeps cached pages in /var/cache/nginx, up to 1 GB, and drops any page nobody has asked for in 60 minutes.
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=site_cache:10m
max_size=1g inactive=60m use_temp_path=off;3. Put the cache in front of your app
Create /etc/nginx/sites-available/example.com with this, changing the name and your app's address:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache site_cache;
proxy_cache_valid 200 301 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
# Never cache or serve cached pages to signed-in visitors.
proxy_cache_bypass $cookie_session $http_authorization;
proxy_no_cache $cookie_session $http_authorization;
add_header X-Cache-Status $upstream_cache_status;
}
}Change $cookie_session to the name of your own login cookie. Nginx already refuses to cache responses that set a cookie or are marked private or no-store, and follows your app's Cache-Control header when it sends one.
Then switch the site on:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/4. Check the settings and reload
sudo nginx -t && sudo systemctl reload nginxnginx -t finds mistakes before they take the site down. Reloading applies the change without dropping visitors.
5. Check it's caching
Ask for the same page twice and look at X-Cache-Status:
curl -sI http://example.com/ | grep -i x-cache-statusThe first answer says MISS, the second HIT. BYPASS means a rule above skipped the cache, which is what you want for signed-in visitors.
What the settings do
proxy_cache_valid: How long a response is kept, by status code, when your app doesn't say with its own Cache-Control header.proxy_cache_use_stale: Serves the last good copy while your app is down, slow or being refreshed, instead of an error.proxy_cache_background_update: Refreshes an expired copy in the background while visitors still get the old one.proxy_cache_lock: When many visitors ask for the same uncached page at once, only one request goes to your app.proxy_cache_bypass: Skips the cache for a request when any of its values isn't empty or 0, like a session cookie.proxy_no_cache: Doesn't save the response for those requests, so one visitor's page is never shown to another.proxy_cache_min_uses: How many times a page must be asked for before it's cached. Useful to keep rarely visited pages out.
Clearing the cache
The free version of Nginx can't remove one page from the cache. To clear everything, delete the cached files, then reload:
sudo find /var/cache/nginx -type f -delete && sudo systemctl reload nginxShorter times in proxy_cache_valid mean you rarely need to.
Hosting with Cloudzyro?
You don't need any of this. Every site on Sites & Apps sits behind Cloudflare, which caches your images, styles and scripts close to your visitors and never caches pages for signed-in visitors. The cache is cleared for you each time a new version goes live.