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 support for a brotli module for their open source version. This means that you will need to compile the NGINX with brotli support along with the brotli module.
Build NGINX with brotli
First, install all the packages that will be needed:
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 being deb-src
):
deb-src <REPO URL> buster main
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, you need to include the brotli module in the build configuration. Open the build rules file at /tmp/nginx-build/nginx-<VERSION>/debian/rules
with a text editor:
nano nginx-<VERSION>/debian/rules
You need to add the following line into the full_configure_flags
section between the --with-
and the --add-dynamic-module
lines:
--add-module=/tmp/nginx-build/ngx_brotli \
Here is the full section shown with the line included:
full_configure_flags := \
$(common_configure_flags) \
--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-stream_ssl_preread_module \
--with-mail=dynamic \
--with-mail_ssl_module \
--add-module=/tmp/nginx-build/ngx_brotli \
--add-dynamic-module=$(MODULESDIR)/http-auth-pam \
--add-dynamic-module=$(MODULESDIR)/http-dav-ext \
--add-dynamic-module=$(MODULESDIR)/http-echo \
--add-dynamic-module=$(MODULESDIR)/http-upstream-fair \
--add-dynamic-module=$(MODULESDIR)/http-subs-filter
Move back into the NGINX source directory:
cd /tmp/nginx-build/nginx-<VERSION>/
Then build NGINX:
dpkg-buildpackage -b
When this finished there will be a large number of NGINX install packages in the directory above. To install the full package move back a directory:
cd ..
Install the .deb
file that begins nginx-full...
dpkg -i nginx-full_<VERSION>_amd64.deb
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
brotli on;
brotli_static on;
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;
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).