Configure the Nginx reverse proxy WordPress cache for Apache

Both Nginx and Apache are very good WEB servers, but in recent years Nginx has become more and more popular, and Apache is a bit old-fashioned, especially in high-traffic scenarios, Nginx is really efficient. So the stationmaster gang has always recommended that everyone choose Nginx first.

If you still like Apache for some reason and want to speed up your WordPress website, you can place a Nginx reverse proxy caching solution in front of Apache.

In the method described in this article, the Nginx reverse proxy cache runs in front of Apache, nginx listens for port 80, and Apache listens for port 8080, nginx is responsible for caching everything it can cache, while sending additional requests to Apache to process PHP, MySQL, or MariaDB, as shown below:

Note: No tutorials are not suitable for WooCommerce. A Nginx proxy cache tutorial for WooCommerce may be published later. If you have any good suggestions, please contact us.

How to configure Apache for the Nginx reverse proxy

Open apache port file:

sudo nano /etc/apache2/ports.conf

Change the port to 8080:

Listen 8080

Open apache virtual host profile:

sudo nano /etc/apache2/sites-available/wordpress.conf

Change the Virtualhost port to 8080:

<VirtualHost *:8080>

Ctrl and X, Y, enter are saved

All Apache virtual host listening ports need to be changed to 8080.

After the nginx is installed and configured, Apache will restart.

Install Nginx

Installing the nginx and package acquisition ngx_cache_purge modules will be easier to manage than the nginx proxy cache.nginx-extras

sudo apt-get install nginx nginx-extras -y

Configure nginx:

sudo nano /etc/nginx/sites-available/reverse

Paste the nginx configuration and we need to prevent this error at the top:proxy_buffer

upstream sent too big header while reading response header from upstream errors with buffers

This is the nginx proxy cache configuration instance (WooCommerce optimization is not supported):

Remember to change the IP address of the server. Web.Server.IP

# WP zhanzhangb nginx proxy cache
# Author Mike from
#fix 504 gateway timeouts, can go in nginx.conf
proxy_connect_timeout       600;
proxy_send_timeout          600;
proxy_read_timeout          600;
send_timeout                600;
#set the location of the cached files, zone, name, size (1000 MB) and how long to cache for 600 minutes
proxy_cache_path  /var/run/proxy_cache levels=1:2 keys_zone=WORDPRESS-PROXY:10m max_size=1000m inactive=600m use_temp_path=off;
proxy_cache_key $scheme$host$request_uri;
#prevent header too large errors
proxy_buffers 256 16k;
proxy_buffer_size 32k;
#httpoxy exploit protection
proxy_set_header Proxy "";
# add forwarded for header
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

server {
listen          80 default;
access_log /var/log/nginx/proxy-access.log;
error_log /var/log/nginx/proxy-error.log;
# show cache status and any skip cache reason
add_header WP-Zhanzhangb-Proxy-Cache $upstream_cache_status;
add_header Cache-BYPASS-Reason $skip_reason;

# define nginx variables
set $skip_cache 0;
set $skip_reason "";

# security for bypass so localhost can empty cache
if ($remote_addr ~ "^(|Web.Server.IP)$") {
    set $bypass $http_secret_header;

# skip caching WordPress cookies
if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
    set $skip_cache 1;
    set $skip_reason Cookie; 

# Don't cache URIs containing the following segments
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|sitemap(_index)?.xml") {
    set $skip_cache 1;
    set $skip_reason URI; 

location / {
	proxy_set_header Host $host;
    # may need to comment out proxy_redirect if get login redirect loop
    proxy_redirect off;
    proxy_cache WORDPRESS-PROXY;
    proxy_cache_revalidate on;
    proxy_ignore_headers  Expires Cache-Control;
    proxy_cache_use_stale  error timeout invalid_header updating http_500 http_502 http_503 http_504;
    proxy_cache_bypass $skip_cache;
    proxy_no_cache $skip_cache;
    proxy_cache_valid 200 301 302 500m;
    proxy_cache_valid 404 1m;
    #can rename PURGE to whatever you want, should restrict it to backend server requests for security
    proxy_cache_purge PURGE from Web.Server.IP;
    # pass requests onto your PHP backend

# allows purging via special URL
location ~ /purge(/.*) {
    allow Web.Server.IP;
    deny all;
    proxy_cache_purge WORDPRESS-PROXY $scheme$host$1;

Ctrl and X, Y, enter are saved

Symlink’s Nginx reverse proxy cache for WordPress virtual hosts is enabled when Nginx is restarted.

Cancel the default Nginx virtual host:

unlink /etc/nginx/sites-enabled/default

Restart Apache and Nginx:

sudo service apache2 restart
sudo service nginx restart

Test the Nginx reverse proxy cache

We can use the cURL to test whether the nginx reverse proxy caches the WordPress website.

Installing the URL:

sudo apt-get install curl -y

Now that the URL is installed, you can start
testing the nginx reverse proxy before Apache to run these URL commands on the Web server using SSH. Now test whether the home page is cached by the reverse proxy, and the -I parameter can get a response header from the reverse proxy server.

curl -I

The key value here is the state, an example of cached results:WP-Zhanzhangb-Proxy-Cache

HTTP/1.1 200 OK
Server: nginx/1.8.1
Date: Wed, 30 Mar 2016 17:32:24 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
WP-Zhanzhangb-Proxy-Cache: HIT

If not cached:WP-Zhanzhangb-Proxy-CacheMISS

HTTP/1.1 200 OK
Server: nginx/1.8.1
Date: Wed, 30 Mar 2016 17:35:53 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
WP-Zhanzhangb-Proxy-Cache: MISS

Note: Sometimes, it may be necessary to cULL the same URL twice to get a HIT response.

How Nginx stores the cache

If you look in a folder, you’ll see a bunch of seemingly random letters and numbers that are determined. This may seem confusing because nginx stores the cache as a URL-based md5 hash value. We used it in the configuration above.proxy_cache_pathlevels=1:2proxy_cache_key$scheme$host$uri

  • $scheme=http
  • $host=domain
  • $request_uri=URL

For example, this page:

  • $scheme Yes https
  • $host Yes,
  • $request_uri 是 /contact-us

We can display it through the md5 generator:

echo | md5sum

You will get this md5 value:


nginx is based on to create a file directory structure.proxy_cache_path levels=1:2

Here the levels are 1:2, 1 (represents) becomes the top-level directory, 2 (represents) becomes its subdirectories, and the md5 hash is the file name, so the path this page store is:7b1


Understanding how nginx caching works can help you selectively remove items from the reverse proxy cache.

Clear the Nginx reverse proxy cache

Thanks to the ngx_cache_purge module included in the nginx-extras module, we can easily clear the cache.

Empty the entire nginx reverse proxy cache

If you want to clear the entire cache, simply delete everything in the proxy-cache directory:

rm -R /var/run/proxy-cache/*

If needed, you can also selectively clear specific folders and subdirectory-specific files generated from the MD5 hash value of the full URL.

If you want to empty the cache using regular expressions (also known as wildcards), the only option is to use nginx Plus,but this can cost a lot of money. The Nginx Plus development team is well aware that having a high-performance WordPress site is important for efficient and flexible caching, so many large companies are willing to pay for it.

Leave a Comment