menu

A Guide to Caching with Nginx

Nginx can be used to cache the content coming from the origin server. We also use Nginx to cache our HTML pages generated by the Node.js server. Nginx can be used as a reverse proxy, load balancer, and cache server at the same time. In this tutorial, we are going to learn how to cache HTML pages generated by the origin server. Our origin server is written in the Node, you can use the same technique with any other technology as well.

READ: Load Balancing Node.js Application Servers with Nginx
READ: How to Setup Nginx with Node.js to Serve Static Files

Assuming you have your origin server running already, you need to install Nginx and proceed with the configuration shown below.

Install Nginx using this command in the Ubuntu:

sudo apt-get update
sudo apt-get install nginx

Here is the sample Nginx reverse proxy configuration. Assuming your origin server is running on port 3000.

All Nginx configuration files are stored in /etc/nginx/conf.d directory. You need to create a new file and store it with the extension .conf. For example, test.conf

upstream my_http_servers {
    server 127.0.0.1:3000;
}

server {
    listen 80;
    server_name yourapp.com;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass         http://my_http_servers;
    }
}

You can use this configuration file to create a simple reverse proxy. Currently, we don’t have cache enabled, so every request will be passed down to the origin server.

In order to verify the cache, you can run this CURL command to any resource of your site.

$ curl -X GET -I 127.0.0.0/index.html
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Fri, 08 Nov 2019 23:24:52 GMT
Content-Type: text/html
Last-Modified: Fri, 08 Nov 2019 23:24:52 GMT
Expires: Fri, 08 Nov 2019 23:24:52 GMT
Cache-Control: no-cache

Check the last key in the response, we have no cache enabled. Let’s enable the cache in the Nginx configuration file and try again.

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=custom_cache:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";

upstream my_http_servers {
    server 127.0.0.1:3000;
}

server {
    listen 80;
    server_name yourapp.com;

    location / {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host $http_host;
        proxy_cache custom_cache;
        proxy_cache_bypass  $http_cache_control;
        add_header X-Proxy-Cache $upstream_cache_status;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass         http://my_http_servers;
    }
}

Save the above file and hit the CURL request again.

$ curl -X GET -I 127.0.0.0/index.html
Date: Fri, 08 Nov 2019 23:24:52 GMT
Content-Type: text/css
Last-Modified: Fri, 08 Nov 2019 23:24:52 GMT
Cache-Control: max-age=31536000
Cache-Control: public
X-Proxy-Cache: HIT

You may need to hit the CURL request more than one time to get Nginx cache the content.

Let’s understand our configuration, at the top, we have added these two lines.

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=custom_cache:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";

proxy_cache_path: This is the path where we save our cache files. levels define the directory hierarchy. keys_zone is the name of our cache to refer to for future purposes. We have given this cache 10MB of storage and instructed Nginx to clear the cache files if it’s not requested within 60 minutes by adding an inactive parameter.

proxy_cache_key: This is the pattern by which we differentiate the cache files.

In our location block, we are telling Nginx to use this cache.

proxy_cache custom_cache;

We are also adding extra HTTP headers to check whether the requested object is coming from a cache server or an origin server.

This is pretty much it. This is the same technique I am using in the Codeforgeek live site.

Conclusion

Caching will improve your website performance and Nginx is battle-tested in the caching field. I am using the same configuration on this live site and our performance is just super awesome. Let me know your performance improvement using the Nginx caching.