How To Install Brotli For NGINX Open Source On Ubuntu 20.04

Brotli is a high-performance, lossless compression algorithm developed and maintained by Google. It can be use by webservers to compress files like .html and .css files and increase the perforce of websites and reduce their bandwidth requirements.

NGINX does not provide a compiled brotli module for their open source version. This means that you will need to compile the NGINX brotli module from source.

Build NGINX with brotli

First, log into your Ubuntu server and install all the build packages that you will need:

apt install brotli git build-essential debhelper po-debconf libexpat-dev libgd-dev libgeoip-dev libhiredis-dev libluajit-5.1-dev libmaxminddb-dev libmhash-dev libpam0g-dev libpcre3-dev libperl-dev libssl-dev libxslt1-dev quilt zlib1g-dev

You will also need to make sure that you have the source code repository enabled in your /etc/apt.d/sources.list file. There should be a line that looks like the following (it should begin deb-src):

deb-src <REPO URL> focal main

If there isn’t then copy the line that starts deb and edit it so that it starts with deb-src they are both shown here:

deb     http://mirrors.digitalocean.com/ubuntu/ focal-updates main restricted
deb-src http://mirrors.digitalocean.com/ubuntu/ focal-updates main restricted

Next, make a build directory and move into it:

mkdir /tmp/nginx-build
cd /tmp/nginx-build

Now, download the NGINX source code from the Debian repositories:

apt source nginx

Download the brotli NGINX module source code:

git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli/
git submodule update --init --recursive
cd ../

Now, move into the NGINX source directory:

cd /tmp/nginx-build/nginx-<VERSION>

Then run this command:

./configure --with-compat --add-dynamic-module=../ngx_brotli

Now, build the nginx module:

make modules

The brotli module is now in /tmp/nginx-build/nginx-<VERSION>/objs/. Copy the module files from this build directory to nginx’s modules folder:

cp /tmp/nginx-build/nginx-<VERSION>/objs/*.so /usr/share/nginx/modules/

Configure NGINX

Next, create the configuration so that NGINX will use the module. First, move to the NGINX configuration directory:

cd /etc/nginx/conf.d/

Create a dedicated configuration file for the brotli module with a text editor:

nano brotli.conf

Copy and past the following contents in the editor

# Enable brotli
brotli on;
brotli_static on;

# File types to compress
brotli_types application/atom+xml application/javascript application/json application/rss+xml
             application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype
             application/x-font-ttf application/x-javascript application/xhtml+xml application/xml
             font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon
             image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;

Next, create the configuration that will load the nginx module:

nano /etc/nginx/modules-available/brotli.conf

Copy and paste the following into this file:

# Load the brotli module
load_module "modules/ngx_http_brotli_filter_module.so";
load_module "modules/ngx_http_brotli_static_module.so";

Next, symlink this file into modules-enabled:

ln -s /etc/nginx/modules-available/brotli.conf /etc/nginx/modules-enabled/

Finally, restart NGINX:

systemctl restart nginx.service

Testing

The last step in any server configuration is testing. This confirms that your changes are working as you expected.

We will use curl to make a tell the server that we want brotli compression -H 'Accept-Encoding: br' and then to only print the connection headers -I of the server’s response:

$ curl -I -H 'Accept-Encoding: br' https://elliotcooper.com

This prints the following reply:

HTTP/2 200
date: Thu, 23 Apr 2020 12:45:55 GMT
server: Apache/2.4.38 (Debian)
strict-transport-security: max-age=15552000; includeSubDomains
last-modified: Wed, 08 Apr 2020 14:53:30 GMT
etag: "15e8-5a2c8a9d7bf77-br"
accept-ranges: bytes
vary: Accept-Encoding
content-encoding: br
content-length: 1539
content-type: text/html

This line:

content-encoding: br

indicates that the server supports serving pages with brotli (br).