acmeextension

How to Setup FastCGI Caching With Nginx Server

By: Sunil Kumar |  In: Server  |  Last Updated: 2018/07/26

As you know Nginx is one of the most popular web server nowadays. It has some cool features. One of these features is FastCGI cache.

The cool thing about FastCGI cache is it does not depend on any external app or plugin. It is an inbuilt functionality of Nginx.

FastCGI cache

Nginx has a FastCGI module which has a directive to cache the dynamic content which is served from the PHP backend.

Setting up FastCGI cache remove the requirement of any other caching solution like varnish or Redis or any specific plugin.

And you can do all the configuration like excluding some content from the caching based on the URL pattern, cookies or any other parameter.

In this article, we assume that you have already installed Nginx and PHP-FPM on your server. If you haven’t any site running on Nginx server you can refer How to Install Nginx on Ubuntu and How to setup server blocks on Nginx server.

Nginx cache works like any other caching service. Nginx define a memory zone for FastCGI where the caching files are stored and php-fpm is configured to use this caching location.

In this article, we will learn how to configure FastCGI cache and php-fpm on Nginx and serve the caching from disk as well as from the RAM.

Enable FastCGI cache on Nginx

To enable FastCGI cache open nginx.conf file

sudo nano -w /etc/nginx/nginx.conf

And add the following code inside the http block

fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=APPNAME:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

After making these changes reload the Nginx server

sudo service nginx reload

FastCGI cache option explanation

fastcgi_cache_path  is the location where cache file will be stored(ofcourse you can use any location on the disk to save the cache). In the above lines cache path is /etc/nginx/cache. The key_zone is the unique name to identify the cache location(APPNAME is this case). And the cache size defined here is 100Mb.

Inactive- this option defines the max age of the cache. It’s very important to define the amount of the time that a cached file can be stored into the cache directory before it is removed from the cache. If a particular cache file is not accessed in last 60 min it will be removed automatically.

fastcgi_cache_key specifies how the cache filenames will be hashed. Nginx encrypts an accessed file with MD5 based on this directive.

Integrating FastCGI cache with PHP-FPM

PHP-FPM is the most popular PHP daemon used with Nginx. To allow PHP-FPM use FastCGI cache add following two line at the end of the configuration file inside location  block.

fastcgi_cache APPNAME;

fastcgi_cache_valid 200 60m;

So here we told fastCGI cache to use the cache location APPNAME which is pointing to /etc/nginx/cache and defined the cache time to 60 min for a request with 200 HTTP status code.

Here is another snippet

fastcgi_cache_valid 200 302 60m;

fastcgi_cache_valid 404 1m;

Here we defined cache time to 60 min for request with 200 and 302 HTTP status code and 1 min for a 404 request.

A complete PHP-FPM configuration with this directive should look similar to this:

location ~ .php$ {
           try_files $uri =404;
           fastcgi_pass   unix:/tmp/php5-fpm.sock;
           fastcgi_index  index.php;
           fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
           include   fastcgi_params;
           fastcgi_buffer_size 128k;
           fastcgi_buffers 256 4k;
           fastcgi_busy_buffers_size 256k;
           fastcgi_temp_file_write_size 256k;
           fastcgi_cache APPNAME;
           fastcgi_cache_valid 200 60m;
       }

After configuring check the Nginx configtest to check everything is fine

sudo service nginx -t

If everything is OK, reload the Nginx server

sudo service nginx reload

Serve FastCGI cache from RAM

As you know RAM memory is much faster as compared to the disk memory. To use RAM memory for caching you have to edit your /etc/fstab file and add the cache directory

nano -w /etc/fstab

And add the following line at the end of this file

tmpfs /etc/nginx/cache tmpfs defaults,size=100M 0 0

NOTE: When using RAM memory for caching you need to keep in mind when you reboot the system you will lose all your cache data and have to generate all the cache again. Also when assigning memory for caching keep in mind that you always assign memory lesser than the RAM available otherwise your other processes will not find any memory to execute.

Now mount the new RAM partition

mount -a

And it should reflect in your partitions

df -ah | grep tmpfs
[root@mylinux:~]
tmpfs              100M 4K 100M 0% /etc/nginx/cache
[root@my.linux:~]

Testing FastCGI Caching

Create a php file on your server which outputs a random number

<?php
/*random.php*/
echo rand();
?>

request this file multiple times from the browser and check the output.

If it output same everytime means caching is working fine.

root@mylinux:~# curl http://localhost/time.php;echo
102
root@mylinux:~# curl http://localhost/time.php;echo
102
root@mylinux:~# curl http://localhost/time.php;echo
102

Also running an ls -alhR over your cache directory should show the cache files that Nginx has generated:

sudo ls -alhR /etc/nginx/cache

Purging the Cache

The naming convention of the cache is based on the variables we set for the “fastcgicachekey” directive.

fastcgi_cache_key "$scheme$request_method$host$request_uri";

So when we hit http://localhost/random.php this is the actual value

fastcgi_cache_key "httpGETlocalhost/random.php";

So when we convert this string to Md5, it would output following

fe767782627e4bf88983d2337ce6fca5

So you will find a cache file in your cache directory with name fe767782627e4bf88983d2337ce6fca5

nano /etc/nginx/cache/e/18/b777c8adab3ec92cd43756226caf618e

So based on this naming convention we can create a purging script which will convert the uri to md5 and remove the file from cache directory.

<!-- purge.php -->

<?php
$cache_path = '/etc/nginx/cache/';
$url = parse_url($_POST['url']);
if(!$url)
{
    echo 'Invalid URL entered';
    die();
}

$scheme = $url['scheme'];
$host = $url['host'];
$requesturi = $url['path'];
$hash = md5($scheme.'GET'.$host.$requesturi);
var_dump(unlink($cache_path . substr($hash, -1) . '/' . substr($hash,-3,2) . '/' . $hash));
?>

and hit POST request to this file with url parameter

curl -d 'url=http://localhost/random.php' http://localhost/purge.php

and the corresponding cache file will be deleted which will be created again when the next time URL is accessed.

Conclusion

Cache systems are evolving, and built in cache mechanisms like FastCGI Cache from Nginx are letting developers get rid of old PHP based caches or any other caching tool like varnish or memcached.

Comments


  • Very well written, not just code, but detailed explanation.
    Thank you, I would see more tech articles on internet like this one 🙂

  • Leave a Comment

    Your email address will not be published.

    *


    Sunil Kumar


    I am the owner of acmeextension. I am a passionate writter and reader. I like writting technical stuff and simplifying complex stuff.
    Know More

    Subscribe to our mailing list


    %d bloggers like this: