WP Rocket – Nginx configuration

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 about. 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!

Leave a Reply

Your email address will not be published. Required fields are marked *