Cache Static Files With NGINX Server


Share On        


One of the major challenging things in modern days in serving your webpages very faster. The faster your webpage loads the quicker your customers will be served and you can retain most of your customers. The longer your website takes to load your customer's switches to some other website.

The webpage loading speed can be made faster by caching your website static files like Images, Stylesheets, Javascripts, Fonts, HTML page and many more in clients devices with the following simple technique.


I am using UBUNTU 18.04 OS. I hope you guys have installed NGINX server. If your wondering about LEMP installation then please check this article How To Install Linux, NGINX, MYSQL, PHP (LEMP Stack) on Ubuntu.


Basically your HTML code will have static files associations with similar structure


<!DOCTYPE html>
<html lang="en">
<head>
    <!-- These are the files that you need to cache -->
    <link rel="stylesheet" href="bootstrap.min.css">
    <link rel="stylesheet" href="bootstrap-datepicker.min.css">
</head>
<body>
    <!-- These are the files that you need to cache -->
    <script src="jquery.min.js"></script>
    <script src="bootstrap.min.js"></script>
</body>
</html>

Step 1 - Go to your NGINX website configuration file. Which usually resides in /etc/nginx/sites-available/*


Here I am having my website configuration with name stackcoder.in

/etc/nginx/sites-available/stackcoder.in

Once you open the file you might be able to see similar to the following.


server {
  root /var/www/html/public;
  index index.php index.html;
  server_name stackcoder.in;

  location / {
    try_files $uri $uri/ /index.php?q=$uri&$args;
  }

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    include fastcgi_params;
  }

  location ~ /\.ht {
      deny all;
  }
}

Step 2 - Now the tricker part comes. The CACHE code.


Use the following code to cache the static files. Before adding the following code in your main NGINX configuration make sure to understand how does it cache.


location ~* \.(gif|otf|jpg|jpeg|png|css|js|ttf)$ {
  add_header Cache-Control public;
  add_header Pragma public;
  add_header Vary Accept-Encoding;
  expires max;
}


Oh! common thats totally fine. But what does that code snippet do?


location ~* \.(svg|gif|otf|jpg|jpeg|png|css|js|ttf)$ { # Anything that ends with .gif .jpg .jpeg .svg .css .js I want to cache
  add_header Cache-Control public; # Cache control header for browsers
  add_header Pragma public; # Cache control header for browsers
  add_header Vary Accept-Encoding; # Cache control header for browsers
  expires max; # Store the static files as long as possible this will be more than a year.
}


You can cache based on hours and days just replace the above last line with any of the following


# Store for 24 hours. You can change accordingly
expires 24h;


# Store for 30 days. You can change accordingly
expires 30d;

Step 3 - Final NGINX configuration file looks similar to the following


server {
  root /var/www/html/public;
  index index.php index.html;
  server_name stackcoder.in;

  location / {
    try_files $uri $uri/ /index.php?q=$uri&$args;
  }

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    include fastcgi_params;
  }

  location ~* \.(gif|otf|jpg|jpeg|png|css|js|ttf)$ {
    add_header Cache-Control public;
    add_header Pragma public;
    add_header Vary Accept-Encoding;
    expires max;
  }

  location ~ /\.ht {
      deny all;
  }
}

Step 4 - RESTART your NGINX server


Don't forget to restart you NGINX server. Else the configuration that you have added wont work.

First check if the NGINX added code to configuration file is proper or not by the following command


sudo nginx -t


You must be able to see similar output


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


Now reload the NGINX server configuration file with the following


sudo service nginx reload


Step 5 - ( CACHE BUSTING ) How to replace CACHED file with new modifications


Hold on before quitting the article just think about the cache files. Once the cache is done thats not the final step. Your CSS / JS or any other static files may change in future. So there must be a way to load this newly loaded change code files instead of old cached files. We call this process as CACHE Busting.

You need to have static global variable in you web application where you can change it when your application static files like CSS / JS as follows.

I am using LARAVEL so I use .env file to store my configurations where I have CACHE Busting constant as follows. You can store your CONSTANTS anywhere but make sure to access those in your HTML file.


CB_VERSION=10


This constant I can use in my application HTML as follows


<link rel="stylesheet" href="bootstrap.min.css?cb={{ env('CB_VERSION') }}">
<link rel="stylesheet" href="bootstrap-datepicker.min.css?cb={{ env('CB_VERSION') }}">


Browser displays it as follows


<link rel="stylesheet" href="bootstrap.min.css?cb=10">
<link rel="stylesheet" href="bootstrap-datepicker.min.css?cb=10">

Step 6- Replacing your cached static file code with updated code


Now think that your CSS / JS or any other static file changes then push the code to production come to .env file and replace the CB_VERSION make sure to increase the number , if you decrease or replace with any older value than there are chances that those versioned cache files to load, if users has not cleared browser cache.

So I will update that by 1 as


CB_VERSION=11


Now once you refresh the page then new modified static contents will be loaded.



Conclusion


Hope this article helped you. I have written other articles on NGINX kindly check them too




AUTHOR

Channaveer Hakari

I am a full-stack developer working at WifiDabba India Pvt Ltd. I started this blog so that I can share my knowledge and enhance my skills with constant learning.

Never stop learning. If you stop learning, you stop growing