Nginx is an open-source and high-performance web server that can be used to speed up content and application delivery. Nginx enhances security, improves scalability, and also can be used as a high availability load balancer. It can be used as a reverse proxy and one of the most important uses of Nginx is content caching. One of the best approaches is to use Nginx as content caching. In this article, we will discuss Nginx FastCGI content caching for better performance of websites.
Enabling FastCGI caching in Nginx
In this article, we assume that you have already installed Nginx with PHP on your Linux machine.
To start enabling FastCGI caching, edit the virtual host configuration file in which caching is to be enabled.
$ cd /etc/nginx/conf.d
$ vi example.conf
Add the following content to the top of the file. Remember that the lines should be outside the server {} directive.
fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri";
Where,
- fastcgi_cache_path – location of the cache
- levels – hierarchy level of cache, it sets up two-level directory hierarchy under /etc/nginx/cache
- keys_zone – memory zone name (In this example I have used MYAPP. You can have your own preference)
- inactive – specifies the time after which cached data that are not accessed during the time specified gets deleted from the cache. In this example, inactive time is set 60m which can be increased or decreased.
- fastcgi_cache_key – It specifies how the cache filenames will be hashed
Variables used in factcgi_cache_key
- $scheme – request scheme HTTPS or HTTP
- $request_method – specifies the request methods such as GET or POST
- $host – Name of the server matching the request
- $request_uri – Full request URI
The location of the cache file can be anywhere on the hard disk but the size should be less than the system’s RAM+swap to avoid the “Can not allocate memory ” issue.
Now go to the location directive where the PHP request is passed to php-fpm. Inside “location ~ \.php$ {}” add the following lines
fastcgi_cache MYAPP;
fastcgi_cache_valid 200 1m;
Where MYAPP is the memory zone name and fastcgi_cache_valid 200 caches all the HTTP 200 responses.
If only time is defined, then 200, 301, and 302 responses are cached.
Run the following command to test the Nginx vhost configuration.
$ nginx -t
Now restart the Nginx service.
$ systemctl restart nginx
A complete vhost configuration file looks like
fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; server { listen 80; root /usr/share/nginx/html; index index.php index.html index.htm; server_name your_server_name; location / { try_files $uri $uri/ /index.html; } location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:unix:/run/php/php8.0-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_cache MYAPP; fastcgi_cache_valid 200 60m; } }
Testing FastCGI caching
Create a simple PHP file in the document root directory.
$ vi /usr/share/nginx/html/info.php
Paste the following content and save
<?php phpinfo(); ?>
Now request the file using curl command or using a browser
If the caching works fine, then you can list the caching directory under /etc/nginx/cache
Add the following line above server{} directive to indicate if the cache was missed or hit
add_header X-Cache $upstream_cache_status;
Restart the Nginx and run the curl command as
$ curl -I http://localhost/info.php
Setting cache exceptions in Nginx fastCGI Cache
Sometimes we may not need to cache dynamic contents such as basic authentications pages. These types of contents can be avoided from being cached based on different variables like “$request_method” “”$request_uri” “$http_cookie” etc.
Below is the sample configuration for cache exception and should be used inside the server{}
directive.
#Cache everything by default set $no_cache 0; #Don't cache POST requests if ($request_method = POST) { set $no_cache 1; } #Don't cache if the URL contains a query string if ($query_string != "") { set $no_cache 1; } #Don't cache the following URLs if ($request_uri ~* "/(cp/)") { set $no_cache 1; } #Don't cache if there is a cookie called PHPSESSID if ($http_cookie = "PHPSESSID") { set $no_cache 1; }
Conclusion
In this article, we learned how to configure Nginx with PHP for dynamic content caching. Also, we learned about different tips to set up cache exceptions.