ℹ️ This post was originally published on our wedding website. Read it there →
How can you add a dynamic PageSpeed module to an already-built instance of NGINX?
For install automation, I’ve summarized the codes and minimal settings in this Bash script. This script was tested to work on the latest stable version of NGINX. If it’s your first time to compile this, feel free to execute the codes step-by-step. It will help you troubleshoot any peculiarities on your system.
/usr/local/sbin/mkpagespeed
You may choose to automate the installation by simply running the script above. In its default settings, it will process the version number you will pass to it. To get your NGINX’s version number run this command:
nginx -v
nginx version: nginx/1.17.1
Since the version number in this example is 1.17.1, after you have downloaded the bash script above, go to the directory where the script is and run these commands:
chmod +x mkpagespeed
./mkpagespeed 1.17.1
Building PageSpeed may take a few minutes and could be a bit resource-intensive, especially on a server with modest specs. If the script runs through errors please let me know so I may make adjustments to it.
Loading the module
To activate PageSpeed, add this line to NGINX’s main configuration file (mine was at /etc/nginx/nginx.conf), outside any block { ... }, on the top-most section of the config file:
nginx/nginx.conf
load_module modules/ngx_pagespeed.so;
# http {
# ...
# }
If you are not sure what your NGINX config file path is, run this command:
nginx -V 2>&1 | grep -o 'conf-path=[^ ]*' | sed 's/conf-path=//'
Configuring filters
What PageSpeed does to your served pages and assets may be fully customized via filters. There are a plethora of configurations to choose from. A pre-selected set of default filters may be activated through:
pagespeed RewriteLevel CoreFilters;
Still, don’t we normally want to fiddle with every little bit of our configuration? Here’s what’s included in my server block:
nginx/sites-available/<your-server.conf>
I also set up PageSpeed Admin Pages, which required the FileCachePath directive to be declared with it. While the Admin Pages location blocks can be retained inside the server block, Admin Pages are declared within the http block, which is outside the **server** block:
nginx/nginx.conf
Updating the module
One potential problem with dynamic modules is when NGINX automatically upgrades via a package manager (e.g. apt, yum, or pacman). If you’re like me, all upgrades in my server are automated by scripts. That may cause a snag because dynamic modules are version-specific. NGINX is set not to load modules that were built for a different NGINX version. So how can PageSpeed modules automatically upgrade when NGINX makes an unattended upgrade?
The answer is to make a hook to the package manager during upgrades. In [apt](https://manpages.ubuntu.com/manpages/xenial/man8/apt.8.html) this may need making two or three simple scripts:
- Hook to
aptand call a worker script. (Alternatively, the hook could directly callmkpagespeedand thus skip the need for a worker script.) - The worker script calls one or more build scripts to update the dynamic modules.
- Build scripts will build and install the new modules just before NGINX upgrades.
Here is how a hook file could look like in /etc/apt/apt.conf.d/:
/etc/apt/apt.conf.d/05nginxmodules
And the worker script could contain this:
/usr/local/sbin/nginx-mod-preinstall
#!/bin/bash
# Call NGINX module build scripts and pass error codes to apt hook
# Get NGINX version to upgrade to
read ngfile < <(grep '/nginx_') || exit 0
ngver=$(echo $ngfile | sed 's/-.*//' | sed 's/.*_//')
# List of build scripts to run:
/usr/local/sbin/mkpagespeed $ngver || exit $?
# /usr/local/sbin/mkbrotli $ngver || exit $?
# /usr/local/sbin/mkmodsec $ngver || exit $?
This worker should point to our build script earlier, that is, [mkpagespeed](/assets/code/mkpagespeed). So there, dynamic module + dynamic upgrades = chill & relax. 😎 Enjoy speed! ⚡
Brotli compression
Google has another open-source project for the next-generation compression called Brotli. If you’re interested with Brotli, you can check this post: Adding Brotli to an Already-built NGINX Instance.