Add Brotli to Nginx

Here I documented a safe and easy way to add brotli to nginx.

Brotli is a generic-purpose lossless compression algorithm that compresses data using a combination of a modern variant of the LZ77 algorithm, Huffman coding and 2nd order context modeling, with a compression ratio comparable to the best currently available general-purpose compression methods. It is similar in speed with deflate but offers more dense compression.

Here is an article that compares the compression algorithms:

Speed up website by compression!

My nginx was installed by apt. Since version1.9.11, nginx began to add support for loading dynamic modules. The method needs another VPS for compiling the brotli module. OK, let’s start.

The codes are on Debian 10. For a better explanation, I name:

  • the VPS that installs nginx –> VPS A
  • the new VPS for compiling the brotli module –> VPS B.

1. Install the essential packages in VPS B

1
sudo apt install -y git build-essential zlib1g-dev libssl-dev libpcre3-dev libgeoip-dev libgd-dev libxml2-dev libxslt1-dev wget

2. Download brotli with git in VPS B

First get run as a root user.

1
sudo -i

Then download the brotli source.

mkdir -p /opt/build
cd /opt/build
git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init

The source is downloaded in /opt/build.

3. Check the version of Nginx in VPS A

1
nginx -V

Then you can see the version of nginx and also the configure arguments like:

1
2
3
4
nginx version: nginx/1.14.2
built with OpenSSL 1.1.1d  10 Sep 2019
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-hfVZV6/nginx-1.14.2=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-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-stream_ssl_preread_module --with-mail=dynamic --with-mail_ssl_module --add-dynamic-module=/build/nginx-hfVZV6/nginx-1.14.2/debian/modules/http-auth-pam --add-dynamic-module=/build/nginx-hfVZV6/nginx-1.14.2/debian/modules/http-dav-ext --add-dynamic-module=/build/nginx-hfVZV6/nginx-1.14.2/debian/modules/http-echo --add-dynamic-module=/build/nginx-hfVZV6/nginx-1.14.2/debian/modules/http-upstream-fair --add-dynamic-module=/build/nginx-hfVZV6/nginx-1.14.2/debian/modules/http-subs-filter

4. Compile in VPS B, and transfer to VPS A

We need to download the same version nginx:

cd /opt/build
wget http://nginx.org/download/nginx-1.14.2.tar.gz
tar -xzvf nginx-1.14.2.tar.gz
cd nginx-1.14.2

Then configure the make file:

1
2
./configure --add-dynamic-module=../ngx_brotli \
--***

On second line, --*** means the configures arguments in VPS A but without the --add-dynamic-module, so the whole command is:

./configure --add-dynamic-module=../ngx_brotli \
--with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-hfVZV6/nginx-1.14.2=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-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-stream_ssl_preread_module --with-mail=dynamic --with-mail_ssl_module

Then make the modules in VPS B:

1
make modules

After the compilation, copy the modules from VPS B to VPS A with scp, and save it in /usr/share/nginx/modules:

1
2
scp objs/ngx_http_brotli_filter_module.so USR@SERVERIP:/usr/share/nginx/modules
scp objs/ngx_http_brotli_static_module.so USR@SERVERIP:/usr/share/nginx/modules

where

  • USR is the user of VPS A
  • SERVERIP is the IP of VPS A
  • if you change the SSH port of VPS A, e.g. 22200, then add -P 22200 after scp
  • if you use the private key to log in VPS A, the key file is in ~/.ssh/key, then add -i ~/.ssh/key after scp

5. Edit the nginx config file in VPS A

1
nano /etc/nginx/nginx.conf

Add the following code in the first line:

1
2
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

Add the following code in http {}:

1
2
3
4
5
brotli on;
brotli_comp_level 4;
brotli_min_length 1k;
brotli_buffers 16 8k;
brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;

6. Test and reload in VPS A

check the config file with:

1
nginx -t

if no failure, then:

1
nginx -s reload
updatedupdated2020-08-292020-08-29