Set Up Nginx FastCGI Cache on Ubuntu 20.04

Nginx is a powerful web application server. However, combined with LEMP situations, PHP is known to be slow with requests needing to go to PHP-FPM, which then queries MySQL/MariaDB database, then Nginx will generate a static HTML page which is then delivered back to Nginx.

So, if a website server is under heavy load, the overheads increase dramatically. However, Nginx has support for a cache solution with FastCGI to reduce the overhead allow a server to handle more page requests with in-demand files being served from a cache instead of having to do the whole route of going to the database and back.

You will be shown how to set it up on an Nginx server on Ubuntu 20.04 LTS Focal in the following guide.

Prerequisites

  • Ubuntu Server 20.04 or onwards.
  • LEMP Stack (Nginx, PHP, MariaDB)
  • Root access or an account with sudo privileges.
  • Curl is installed
  • Up to date system packages.
sudo apt update && sudo apt upgrade -y \
 sudo apt install curl

Advertisement


How to Configure Nginx FastCGI Cache

Edit Nginx Configuration File

You will need to open your nginx.conf file with a text editor in the first part. The guide will use the nano text editor.

sudo nano /etc/nginx/nginx.conf

Now, in the HTTP part, you will need the following lines.

fastcgi_cache_path /var/nginx/fastcgi_cache levels=1:2 keys_zone=fcgicache:150m max_size=20g inactive=60m use_temp_path=off;
 fastcgi_cache_key "$scheme$request_method$host$request_uri";

Once entered, CTRL+O then type “Y”, then CTRL+X to exit.

Explanation of the settings you entered in your nginx.conf file.

  • fastcgi_cache_path – specifies the location of your FastCGI cache (/var/nginx/fastcgi_cache/).
  • levels=1:2 – creates a two-level directory hierarchy under your cache location. The purpose of this is to spread out files in two directories instead of all files being requested from the same source, which can cause slowdowns.
  • keys_zone – specifies the name of the shared memory zone name (fastcgi_cache) and its size (120M). This is the memory zone for storing cache keys and metadata during demand.
  • max_size – sets the max size of the cache. The example shows 20GB. Once filled, it will then remove the most used files. Failure to fix this will see the entire disk fill up.
  • inactive – remove data that has been inactive for a specified period. In the example, it’s set for 60 minutes. Note, you can set this as high as you like or as low.
  • use_temp_path – instructions Nginx to write files for the cache directly to the folder you specified and avoids Nginx copying the files first to a temporary storage area which is not needed.
  • fast_cgi_cache_key – defines the key for cache lookup. Nginx adds an MD5sum hash function on the cache key and uses the hash result as the name of cache files.

Edit Nginx Server Block

Now you need to set up your server block. First, open your location block as follows.

sudo nano /etc/nginx/sites-available/example.com.conf

With having LEMP already installed, you will have a location block for (~/.php$) to add the following.

fastcgi_cache fcgicache;
 fastcgi_cache_valid 200 60m;
 fastcgi_cache_use_stale error timeout updating invalid_header http_500 http_503;
 fastcgi_cache_min_uses 1;
 fastcgi_cache_lock on;
 add_header X-FastCGI-Cache $upstream_cache_status;

FastCGI Cache Purge

Now, create a Cache Purge directive if the cache needs to be purged manually.

Fastcgi-Purge Config
 location ~ /purge(/.*) {
 Uncomment the following two lines to allow purge only from the webserver
 allow 127.0.0.1;
 deny all;
 fastcgi_cache_purge fcgicache "$scheme$request_method$host$1";
 } 

Once entered, CTRL+O then type “Y”, then CTRL+X to exit.

Now test your Nginx configuration before a restart.

sudo nginx -t

The output should be if correct:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
 nginx: configuration file /etc/nginx/nginx.conf test is successful

Now restart your Nginx server for changes to take effect.

sudo systemctl restart nginx

Explanation of the settings you entered in your server block file (example.com.conf).

  • fastcgi_cache – this instructs Nginx to enable caching using the memory zone defined set in (fastcgi_cache_path) in your Nginx.conf set-up.
  • fastcgi_cache_valid – sets the cache time HTTP status codes, this can be modified to shorter, or longer periods as well you can change the status codes. Do not remove code 200, which must stay at all times.
  • fastcgi_cache_use_stale – sets the number of times the resource gets requested by clients before Nginx caches it.
  • fastcgi_cache_lock – when set to on, initial requests are served first, with others waiting for those requests to be completed first. If set to off, all requests go straight to the PHP-FPM server.
  • add_header – adds an X-FastCGI-Cache header in the HTTP response. This will show if the FastCGI cache served the request or not with a hit or miss.

Create Folder for FastCGI Cache

Create a folder that we specified in our path for Nginx to cache the files too.

sudo mkdir -p /var/nginx/fastcgi_cache

Advertisement


Test Nginx FastCGI Cache

Now, test your cache with the curl command below. Note that you may need to trigger the command a few times before a cache hits, depending on your specified settings.

curl -I http://www.your-domain.com

Look in your Output for (X-FastCGI-Cache: Hit).

~$ curl -I https://www.linuxcapable.com/
 HTTP/1.1 200 ok
 Date: Wed, 16 Jun 2021 06:22:42 GMT
 Connection: keep-alive
 Cache-Control: max-age=3600
 Expires: Wed, 16 Jun 2021 07:22:42 GMT
 Location: https://www.linuxcapable.com
 cf-request-id: 0ab51591810000df280931a000000001
 NEL: {"report_to":"cf-nel","max_age":604800}
 X-FastCGI-Cache: Hit
 X-Content-Type-Options: nosniff
 Server: cloudflare
 CF-RAY: 6601f1fc091cdf28-MEL

FastCGI Cache files to ignore

Certain website features should not be cached at all. For example, for WordPress sites, comment sections in website feedback/replies feed, sitemaps, for instance, should be set to avoid. You can do this by entering the following code to exempt these items above the location (~\.php$) line.

cache by default
 set $skip_cache 0;
 do not cache uri's containing the following, add more as required
 if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-..php|^/feed/|/tag/./feed/|index.php|/.sitemap..(xml|xsl)") {
     set $skip_cache 1;
 }
 do not use the cache for logged in users/comments
 if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
     set $skip_cache 1;
 }
 requests with query string go straight to PHP not cache.
 if ($request_method = POST) {
     set $skip_cache 1;
 }
 if ($query_string != "") {
     set $skip_cache 1;
 }

If you would like debugging, you can add under each (set $skip_cache 1;) the following to enable.

set $skip_reason "note of your choice";

Advertisement


Comments and Conclusion

With an existing Nginx and LEMP set-up, the guide has shown you how to implement a FastCGI Cache directive to your server, which can improve performance by reducing the number of requests to your PHP-FPM during peak times. This will then go on to reduce system load, which all websites strive for perfection.

FastCGI is beneficial for CMS websites such as WordPress who have plugins that can work hand in hand with the caching technology, and those can be found in the plugin sections of those CMS products.

Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x