Add Brotli To Nginx On Debian Stretch

Table Of Contents

Installation

Normally I just install nginx this way:

Add the lines to /etc/apt/sources.list:

deb http://nginx.org/packages/mainline/debian/ stretch nginx
deb-src http://nginx.org/packages/mainline/debian/ stretch nginx

If the key hasn't been added, add it:

sim@server:~$ wget https://nginx.org/keys/nginx_signing.key && sudo apt-key add nginx_signing.key

Then install it:

sim@server:~$ sudo apt update && sudo apt install nginx

Brotli: Basic Settings

THe brotli is not included in the prebuilt package. So I have to build it from source.1

As of now, my installed nginx is v1.17.0, so I have to download the version of nginx for complie purpose:

sim@server:~$ wget https://nginx.org/download/nginx-1.17.0.tar.gz && tar zxvf nginx-1.17.0.tar.gz && rm nginx-1.17.0.tar.gz

Then clone ngx_brotli from github:

sim@server:~$ git clone https://github.com/eustas/ngx_brotli.git
sim@server:~$ cd ngx_brotli && git submodule update --init && cd ~

Install the build dependencies:

sim@server:~$ sudo apt build-dep nginx

Make the modules and copy it to the right place:

sim@server:~$ cd ~/nginx-1.17.0
sim@server:~/nginx-1.17.0$ ./configure --with-compat --add-dynamic-module=../ngx_brotli
sim@server:~/nginx-1.17.0$ make modules
sim@server:~/nginx-1.17.0$ sudo cp objs/*.so /usr/lib/nginx/modules

/etc/nginx/nginx.conf:

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

Include the lines in server blocks that need the brotli:

server {
  ...
  brotli on;
  brotli_static on;
  brotli_types *;
  ...
}

Don't include the lines in http block directly since it will force all the server blocks to use brotli, which will a nightmire when it affects a backend server...... Things like brotli should be only used in frontend server blocks.

Restart nginx:

sim@server:~/nginx-1.17.0$ sudo systemctl restart nginx

The other third party modules not included in the prebuilt package can be installed this way as well.

Brotli: More ON settings

The following settings might be useful due to the following reasons2:

  1. Brotli with setting 4 is both significantly smaller AND compresses faster than gzip
  2. Brotli is made text-based file formats like HTML (included by default), plaintext, JavaScript, JSON, SVG and RSS
  3. Pre-compress the static formats so these can be served immediately for every request

But it is not useful for me when I'm using proxy_pass to a backend from a frontend. So brotli_static means nothing when I fetch the files from another server. Proxying static files lowers the speed. I'd rather upload files to multiple servers (My way of doing this via Git).

/etc/nginx/conf.d/default.conf:

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

...
server {
  server_name snorl.ax;
  ...
  brotli on;
  brotli_comp_level 4;
  brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;

  brotli_static on;
  ...
}

The site is generated by Pelican, a static site generator, which means the site files are mostly text-based formats. So a bash is made to process them before the files are published:

#!/bin/bash

for FILE in $(find public -type f -iname '*.css' -o -iname '*.js' -o -iname '*.svg' -o -iname '*.json' -o -iname '*.html' -o -iname '*.xml'); do
    echo -n "Compressing ${FILE}..."
    brotli -f ${FILE} -o ${FILE}.br;
    echo "done."
done

Then after publishing the files, the pre-processed .brs will be served.

Created: Updated: In a Terminal SessionTags: