I prefer open-source software and have been a long-time advocate of OSS in general. Recently, I started liking WP Rocket plugin that offers some unique features. I already have a perfect Nginx configuration for WP Super Cache plugin (that I consider as the best full-cache plugin till date). Since, WP Rocket uses disk caching like WPSC, I wanted to quickly convert the existing configurations to fit WP Rocket. I did succeed in it and you can find it in my WordPress-Nginx repo. Here I explain how WP Rocket stores the cached content and how it could be integrated into Nginx.
We begin with the classic location block that looks like this…
# version 1
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
Our aim is to modify it to fit WP Rocket by the end of this little article.
Let’s start with the home page. The cache for the home page is stored at /wp-content/cache/wp-rocket/example.com/index.html
. We can easily find the value of example.com through the variable named $host in Nginx. The following code will search for the cached content before passing the request to the PHP.
# version 2
location / {
try_files "/wp-content/cache/wp-rocket/$host/index.html" $uri $uri/ /index.php$is_args$args;
}
It’s time to by-pass cache on particular scenarios, such as logged-in users. We need to use version #1 mentioned earlier for logged-in users and version #2 for others who can use cached content, if exists. So, how can we split the requests based on cookies (or any other similar factor)? There is no doubt that we need to use if
statement and we need to use two location block to match different kind of requests (logged-in users and non-logged-in users). The recommend solution is to use a non-standard HTTP status code and then divert the configuration based on a condition. Here’s the snippet taken directly from the official Nginx page…
location / {
error_page 418 = @other;
recursive_error_pages on;
if ($something) {
return 418;
}
# some configuration
...
}
location @other {
# some other configuration
...
}
In the above code, if the condition $something
is false, then # some configuration
is executed. If the condition is true, then # some other configuration
is executed. Did you get it? I know it could take a while to grab in. When you are ready, let’s use the same technique to divert our requests based on the cookie for logged-in user…
# version 3
location / {
error_page 418 = @cachemiss;
recursive_error_pages on;
if ($http_cookie ~* "wordpress_logged_in_") { return 418; }
# executed only for general visitors (who are not logged-in)
try_files "/wp-content/cache/wp-rocket/$host/index.html" $uri $uri/ /index.php$is_args$args;
}
location @cachemiss {
# executed only for logged-in users
try_files $uri $uri/ /index.php$is_args$args;
}
Note: you may use any HTTP status code that isn’t used elsewhere.
Let’s add a couple of more cookie checks to bypass cache for commenters and password-protected posts…
# version 4
location / {
error_page 418 = @cachemiss;
recursive_error_pages on;
if ($http_cookie ~* "wordpress_logged_in_") { return 418; } # logged-in users
if ($http_cookie ~* "comment_author_") { return 418; } # commenters
if ($http_cookie ~* "wp_postpass_") { return 418; } # password protected posts
try_files "/wp-content/cache/wp-rocket/$host/index.html" $uri $uri/ /index.php$is_args$args;
}
location @cachemiss {
try_files $uri $uri/ /index.php$is_args$args;
}
Now, cookies are taken care. We also need to bypass the cache on the following conditions…
- For POST requests.
- For search requests (format: example.com/?s=search_query).
- To view pages by ID (format: example.com/?p=id_of_the_post)
- For AMP test requests (format: example.com/?amp=1)
- For previewing of posts while editing them (format: example.com/?preview=true).
When we add support for all the above, our config would become…
# version 5
location / {
error_page 418 = @cachemiss;
recursive_error_pages on;
if ($http_cookie ~* "wordpress_logged_in_") { return 418; }
if ($http_cookie ~* "comment_author_") { return 418; }
if ($http_cookie ~* "wp_postpass_") { return 418; }
# bypass cache for common query strings
if ($arg_s != "") { return 418; } # search query
if ($arg_p != "") { return 418; } # request a post / page by ID
if ($arg_amp != "") { return 418; } # amp test
if ($arg_preview = "true") { return 418; } # preview post / page
try_files "/wp-content/cache/wp-rocket/$host/index.html" $uri $uri/ /index.php$is_args$args;
}
location @cachemiss {
try_files $uri $uri/ /index.php$is_args$args;
}
Well, now, we have a working configuration to server cached content from WP Rocket Plugin. There are lot more to it than what’s discussed above. For example, I’ve only talked about home page so far. Also, we need to add support for SSL. You can find the complete Nginx configuration for WP Rocket Plugin at my repo. If you need explanation for the entire configuration, please say so in the comment section below. If there is enough interest, I will add it later. Happy caching!
Thank you so much for this hack! I’m using your nginx config on my server, and it’s incredible boost my site!
That’s nice to know!
Thank you so much for this hack! I’m using your nginx config on my server, and it’s incredible boost my site!
Hola,
Fenomena la explicación, pero la configuracion completa no aparece. Hay un 404 en el enlace que pusiste. Se puede ver la configuracion completa en nginx?
Saludos!
Gracias por notificar sobre el enlace muerto. Está arreglado ahora.
This line is wrong:
try_files “/wp-content/cache/wp-rocket/$host${uri}$is_args$args/index$https_suffix.html” $uri $uri/ /index.php$is_args$args;
When I run nginx -t it say:
nginx: [emerg] unknown “https_suffix” variable …test failed
Can you fix that code ????
https_suffix variable is defined in conf.d/common.conf file as can be seen at https://github.com/pothi/wordpress-nginx/blob/master/conf.d/common.conf#L36 . Thanks.
you just forget declare Map on nginx.conf
like this
> # For SSL Compatibility – WP Super Cache and WP Rocket depend on this
> map $scheme $https_suffix { default ”; https ‘-https’; }
It is defined in https://github.com/pothi/wordpress-nginx/blob/master/conf.d/common.conf#L33-L38
Hey Pothi,
quick question,
WPSUperCache generate files like meta-wp-cache-UUID.php and wp-cache-UUID.php
but in your configuration we call index.html and sometimes with suffix-https
something wrong, my server always render pages :/ BCQ nginx can’t see cache static files
Please make sure that in example.com/wp-admin/options-general.php?page=wpsupercache , under Advanced => Cache Delivery Method, “Expert” is selected instead of “Simple”. Save and clear the cache. WP Super Cache would start creating index.html files going forward.
Thanks for your sharing. It’s helpful for my server.
Thanks for sharing!
But how make it work together with nginx cache?
Unfortunately, my configuration wouldn’t work with Nginx cache, as both types of Nginx cache, particularly the purging method, are available only as part of commercial subscription from Nginx. Thank you.