How to Install NGINX FastCGI Cache Purge Module Without Re-installing NGINX in Ubuntu Server

Recently I have enabled NGINX FactCGI caching in our Digital Ocean Droplet in order to reduce the Time To First Byte (TTFB) of this blog. However, one drawback of this caching is there is no support provided by the Nginx Open Source webserver to purge the cache when a page is modified. There is a separate ngx_cache_purge module available which has to be compiled with Nginx code to enable cache purging.

Disclosure: Please note that some of the links in the post are referral links. Read more about the policy here.

There are 3 solutions to add this module to Nginx:

  1. Compile NGINX & Cache Purge Module. It will pollute the production system with compilation software. Also, we need to recompile with every new Nginx version.
  2. Go for Nginx plus paid version
  3. Compile NGINX with NGX_CACHE_PURGE module in a development server and copy the compiled module to the NGINX in the production server and load it. Also, we need to recompile with every new Nginx version.

Obviously, I went with the 3rd solution since I don’t want our blog to be down and I don’t wanna pollute the production system. Let’s see how we can compile the NGX_CACHE_PURGE module and load it to the running Nginx in the production server.

Step 1: Get Nginx Configure Arguments

Run the following command in the production server:

nginx -V

Output

nginx version: nginx/1.14.0 (Ubuntu)
built with OpenSSL 1.1.1  11 Sep 2018
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-H4cN7P/nginx-1.14.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module

Make note of the currect version and copy all the configure arguments which starts with --with- and keep it for use later

Step 2: Get Nginx Source Code

Get the Nginx source code of the version that is installed in your production server. I would recommend to do these operations in a non-prod server. So that we don’t end up polluting the production server with unnessary softwares.

I’ve created a new Digital Ocean Droplet just for this compilation. Now let’s login to the dev server and navigate to the /tmp/ directory and execute the following command.

wget http://nginx.org/download/nginx-1.14.0.tar.gz

Step 3: Get Nginx Cache Purge Code

At the time of this writing, 2.3 is the latest version. You can check the latest version here.

wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz

Step 4: Extract the files

for filename in *.tar.gz; do tar zxf $filename; done

Step 5: Replace Config File

Get this config file which was updated with the ability to compile the module as dynamic.

wget https://raw.githubusercontent.com/nginx-modules/ngx_cache_purge/master/config

Now replace the ngx_cache_purge-2.3/config file with the above one.

cp config ngx_cache_purge-2.3/config

Step 6: Install Build Essentials and Libraries

apt-get update && apt-get install build-essential

HTTP rewrite module requires the PCRE library.

apt-get install libpcre3-dev

SSL modules require the OpenSSL library

apt-get install libssl-dev

HTTP gzip module requires the zlib library

apt-get install zlib1g-dev

HTTP XSLT module requires the libxml2/libxslt
libraries.

apt-get install libxml2-dev libxslt1-dev

HTTP image filter module requires the GD library

apt-get install libgd-dev

GeoIP module requires the GeoIP library

apt-get install libgeoip-dev

Step 7: Add Nginx Cache Purge Dynamic Module

Navigate to the nginx-1.14.0 directory

cd nginx-1.14.0

Execute the following command with the configure arguments that we copied in Step 1. If you don’t include all the configure arguments, then the compiled module will not be compatible with the Nginx running in the production server.

./configure --add-dynamic-module=../ngx_cache_purge-2.3

So the final command would be something like this:

./configure --add-dynamic-module=../ngx_cache_purge-2.3 --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-H4cN7P/nginx-1.14.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module

Note: You may get errors due to missing dependencies required for compilation. Just install the required libraries if it complains.

If it executes successfuly, then the output would be something similar to this:

configuring additional dynamic modules
adding module in ../ngx_cache_purge-2.3
 + ngx_http_cache_purge_module was configured
checking for PCRE library ... found
checking for PCRE JIT support ... found
checking for OpenSSL library ... found
checking for zlib library ... found
checking for libxslt ... found
checking for libexslt ... found
checking for GD library ... found
checking for GD WebP support ... found
checking for GeoIP library ... found
checking for GeoIP IPv6 support ... found
creating objs/Makefile

Configuration summary
  + using threads
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/share/nginx"
  nginx binary file: "/usr/share/nginx/sbin/nginx"
  nginx modules path: "/usr/lib/nginx/modules"
  nginx configuration prefix: "/etc/nginx"
  nginx configuration file: "/etc/nginx/nginx.conf"
  nginx pid file: "/run/nginx.pid"
  nginx error log file: "/var/log/nginx/error.log"
  nginx http access log file: "/var/log/nginx/access.log"
  nginx http client request body temporary files: "/var/lib/nginx/body"
  nginx http proxy temporary files: "/var/lib/nginx/proxy"
  nginx http fastcgi temporary files: "/var/lib/nginx/fastcgi"
  nginx http uwsgi temporary files: "/var/lib/nginx/uwsgi"
  nginx http scgi temporary files: "/var/lib/nginx/scgi"

Step 8: Make Modules

make modules

This command will throw some casting errors. Just ignore them. At this point, the cache purge module would have already compiled as ngx_http_cache_purge_module.so in the objs directory.

Step 9: Enable Nginx Cache Purge Module

Now you can copy ngx_http_cache_purge_module.so file to Nginx’s modules directory in the production server. To enable this module, add the following to /etc/nginx/nginx.conf and reload Nginx:

load_module modules/ngx_http_cache_purge_module.so;

For me I had to configure differently. First I had copied this file to the modules directory from the tmp folder in the live server.

sudo cp ngx_http_cache_purge_module.so /usr/lib/nginx/modules/

Then, created a new file mod-http-cache-purge.conf in the /usr/share/nginx/modules-available directory with the load_module directive:

load_module modules/ngx_http_cache_purge_module.so;

Then, created a symlink with the following command

ln -s /usr/share/nginx/modules-available/mod-http-cache-purge.conf /etc/nginx/modules-enabled

Then, reloaded Nginx. Whenever you change your NGINX config, run sudo nginx -t before you do “sudo service nginx reload” just to make sure you don’t break stuff.

sudo service nginx reload

References

https://github.com/FRiCKLE/ngx_cache_purge/issues/63

Conclusion

That’s all folks. In this article, we have added Cache Purging support to our existing Nginx web server without any down time in the live server.

Leave a Reply