Add Brotli To Nginx On Debian Stretch

Table Of Contents


Normally I just install nginx this way:

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

deb stretch nginx
deb-src stretch nginx

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

sim@server:~$ wget && 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 && 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
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


load_module modules/;
load_module modules/;

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).


load_module modules/;
load_module modules/;

server {
  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:


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."

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

Created: Updated: In a Terminal SessionTags: