How to Add Brotli Support to Nginx on Ubuntu 18.04 | 16.04

This brief tutorial shows students and new users how to add Brotli support to Nginx when using Ubuntu 18.04 | 16.04.

Brotli ( br for short), is an open source compression algorithm developed by Google that can be used as an alternative to Gzip, Zopfli and Deflate. In some studies, data can be compressed by 10 to 20 percent more than current compression algorithms.

If you want to use Brotli with Nginx, you’ll have to use the ngx_brotli module developed by Google, since Nginx doesn’t have an official support, at least for its free version.

Nginx commercial version might have support for Brotli.

When you’re ready to including Brotli support with Nginx, follow the steps below:

Step 1: Install SSL Certificates

Brotli requires SSL. Nginx will need to have SSL support before you’ll be able to use Brotli. Since Let’s encrypt is easy to install and use with Ubuntu, use the steps below to install Let’s Encrypt free SSL certificate.

Before generating your free wildcard certificates, you’ll first want to make sure certbot is installed and running. To install it, run the commands below:

sudo apt update
sudo apt-get install letsencrypt

The commands above will install certbot tool and all dependencies that will be allowed to make the tool function.

Now that the tool is installed, you can now proceed to generating certificates.

Let’s Encrypt provides many ways to challenge you to validate that you own the domain you want to provide SSL certificates for. You will not be able to generate certificates if you can’t prove that you own the domain you want certificates for.

However,  for wildcard certificates, the only challenge method Let’s Encrypt accepts is the DNS challenge, which we can invoke via the preferred-challenges=dns flag.

So, to generate a wildcard cert for domain *.example.com, you run the commands below:

sudo certbot certonly --manual --preferred-challenges=dns --email [email protected] --server --agree-tos -d *.example.com

The command options above are explained below:

  • certonly:                                     Obtain or renew a certificate, but do not install
  • –manual:                                    Obtain certificates interactively
  • –preferred-challenges=dns:      Use dns to authenticate domain ownership
  • –server:                                      Specify the endpoint to use to generate
  • –agree-tos:                                 Agree to the ACME server’s subscriber terms
  • -d:                                               Domain name to provide certificates for

After executing the command above, Let’s Encrypt will provide a text string to add a text record to your DNS entry.

Example:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: y
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for example.com

-------------------------------------------------------------------------------
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.

Are you OK with your IP being logged?
-------------------------------------------------------------------------------
(Y)es/(N)o: y

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.example.com with the following value:

x4MrZ6y-JqFJQRmq_lGi9ReRQHPa1aTC9J2O7wDKzq8

Before continuing, verify the record is deployed.

Go to your DNS provider portal and add a text record for the string above and save.

Let's Encrypt DNS

Wait a few mins before continuing from the prompt. Some DNS providers take a wile to propagate changes so it may depend on your provider’s platform.

After the changes above and Let’s encrypt is able to validate that you own the domain, you should see a successful message as below:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2020-01-09. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   
   Donating to EFF:                    

That should do it!

The wildcard certificate is now generated and ready to be used.

To verify that the certificate is ready, run the commands below:

sudo certbot certificates

That should display similar screen as below:

Found the following certs:
  Certificate Name: example.com
    Domains: *.example.com
    Expiry Date: 2020-01-05 07:48:04+00:00 (VALID: 85 days)
    Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem

You’re all set!

Now, Let’s Encrypt’s certificates are valid for 90 days. You’ll want to setup a crob job to automate the renewal process. To do that, open crontab and add the entry below:

sudo crontab -e

Then add the line below and save.

0 1 * * * /usr/bin/certbot renew >> /var/log/letsencrypt/renew.log

Save and you’re done!

Step 2: Install Nginx

If you don’t already have Nginx HTTP server installed, then use the steps below to download and install it from its office repository.

You can get the latest stable version of NGINX from the NGINX PPA on Launchpad.

Run the commands below to get the latest stable version from Nginx PPA.

sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository ppa:nginx/stable
sudo apt-get update
sudo apt-get install nginx

After installing Nginx, run the commands below to check the version installed

sudo nginx -v

You should see similar lines as below:

Output:
nginx version: nginx/1.16.1

Step 3: Download and compile the Brotli

At this point, you should have Let’s Encrypt Wildcard SSL installed as well as Nginx.

The next step is to build ngx_brotli module for Nginx as a dynamic module.

For this to work, you’ll need to compile Brotli using the correct version of Nginx installed. Fro our test above, you have Nginx version 1.16.1 so we’ll need to compile ngx_brotli module for that specific version.

First, installed required libraries by running the commands below.

sudo apt install git libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev

After that, download Nginx version that matches the current installed version. Then extract it using the commands below:

cd ~/
wget https://nginx.org/download/nginx-1.16.1.tar.gz
tar zxvf nginx-1.16.1.tar.gz

After extracting it, go and clone ngx_brotli module from Github using the commands below:

cd ~/
git clone 
cd ~/ngx_brotli
git submodule update --init

Change into nginx-1.16.1 folder in your home directory.

cd ~/nginx-1.16.1

After that, compile the ngx_brotli as a dynamic module by running the commands below. Then copy it to the standard directory for Nginx modules at /etc/nginx/modules.

./configure --with-compat --add-dynamic-module=./ngx_brotli
make modules
sudo cp objs/*.so /etc/nginx/modules-available
or 
sudo cp objs/*.so /usr/share/nginx/modules

List files in /etc/nginx/modules-available and you will see

ngx_http_brotli_filter_module.so
ngx_http_brotli_static_module.so

Step 4: Configure Nginx

At this point, we’re ready to load ngx_brotli module.

Open your default nginx.conf file and load up the two modules you just compiled.

sudo nano /etc/nginx/nginx.conf

Then add the following two directives at the top of the file to load new Brotli modules.

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

Your nginx.conf file should look similar to this:

load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {
...

After that, run Nginx test to see if you get any errors.

sudo nginx -t

You should get similar lines as shown below if everything is successful.

Output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

That it!

When when you want to use Brotli with your virtual host configuration files, use the example below:

server {
listen 80;
server_name example.com;
return 301 
}

server {
listen 443 ssl http2;
server_name example.com;

ssl_certificate /etc/letsencrypt/example.com/fullchain.cer;
ssl_certificate_key /etc/letsencrypt/example.com/example.com.key;

brotli on;
brotli_static on;
brotli_types *;
}

Restart Nginx

sudo systemctl reload nginx.service

That should do it!

Conclusion:

This post showed you how to configure Nginx HTTP server with Brotli to support fast compression. If you find any error above, please use the comment form below to report it.

Thanks,

You may also like the post below: