Introduction
NGINX is an open-source project created by Igor Sysoev and was released back in 2004. NGINX is commonly used for load balancing, reverse proxying and as a web server.
gzip is a lossless data compression utility. When a user visits a website, resources like images, javascript, stylesheets, and others are commonly compressed with gzip.
Brotli is a new compression algorithm, using a pre-defined dictionary with common keywords and phrases on both client and server side. It is supported by all major browsers.
Prerequisites
- A server running Ubuntu 16.04/18.04/18.10/19.04.
- Root access
- Preinstalled NGINX (optional)
Step 1 – Install and Configure NGINX
Step 1.1 – Pre-installation steps
Check Ubuntu version:
root@example-server:~# lsb_release -ds
Ubuntu 18.04.2 LTS
Update operating system’s packages:
apt update && apt upgrade -y
Step 1.2 – Build NGINX from source
NGINX is written in C, so we need to install compiler tools.
apt install -y build-essential git tree
Now download the latest version of NGINX source.
wget https://nginx.org/download/nginx-1.17.0.tar.gz && tar zxvf nginx-1.17.0.tar.gz
In order to compile NGINX from a source, we need to download NGINX dependencies.
PCRE
wget https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz && tar xzvf pcre-8.43.tar.gz
Zlib
wget https://www.zlib.net/zlib-1.2.11.tar.gz && tar xzvf zlib-1.2.11.tar.gz
OpenSSL
wget https://www.openssl.org/source/openssl-1.1.1c.tar.gz && tar xzvf openssl-1.1.1c.tar.gz
Brotli
#Before downloading Brotli you can check and this repo: https://github.com/yverry/ngx_brotli.git, both of the repositories are maintained, you can choose which of the repo to use.
git clone https://github.com/eustas/ngx_brotli.git
cd ngx_brotli
git submodule update --init --recursive
Note: In newer versions of Ubuntu, apt update
is executed after adding the repository.
add-apt-repository -y ppa:maxmind/ppa
apt update && apt upgrade -y
apt install -y perl libperl-dev libgd3 libgd-dev libgeoip1 libgeoip-dev geoip-bin libxml2 libxml2-dev libxslt1.1 libxslt1-dev
Step 1.3 – Compile NGINX with Brotli
Enter NGINX folder.
cd ~/nginx-1.17.0
Configure NGINX and build it. Build time takes about 5 min, depending on the system configuration.
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --user=nginx --group=nginx --build=Ubuntu --builddir=nginx-1.17.0 --with-select_module --with-poll_module --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-perl_modules_path=/usr/share/perl/5.26.1 --with-perl=/usr/bin/perl --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module=dynamic --with-stream_ssl_preread_module --with-compat --with-pcre=../pcre-8.43 --with-pcre-jit --with-zlib=../zlib-1.2.11 --with-openssl=../openssl-1.1.1c --with-openssl-opt=no-nextprotoneg --with-debug --add-module=../ngx_brotli --sbin-path=/usr/sbin/nginx
make && make install
After building NGINX, we should create a symlink with the new modules.
ln -s /usr/lib/nginx/modules /etc/nginx/modules-enabled
Check the NGINX version and the parameters.
nginx -V
Output:
nginx version: nginx/1.17.0 (Ubuntu)
built by gcc 8.3.0 (Ubuntu 8.3.0-6ubuntu1)
built with OpenSSL 1.1.1c 28 May 2019
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --user=nginx --group=nginx --build=Ubuntu --builddir=nginx-1.17.0 --with-select_module --with-poll_module --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-perl_modules_path=/usr/share/perl/5.26.1 --with-perl=/usr/bin/perl --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module=dynamic --with-stream_ssl_preread_module --with-compat --with-pcre=../pcre-8.43 --with-pcre-jit --with-zlib=../zlib-1.2.11 --with-openssl=../openssl-1.1.1c --with-openssl-opt=no-nextprotoneg --with-debug --add-module=../ngx_brotli --sbin-path=/usr/sbin/nginx
Step 1.4 – Create a user and group
User is created with no home directory and with disabled login and password.
adduser --system --home /nonexistent --shell /bin/false --no-create-home --disabled-login --disabled-password --gecos "nginx user" --group nginx
Check NGINX for any errors:
service nginx configtest
OR
nginx -t
On fresh Ubuntu installation you will see this error:
nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (2: No such file or directory)
Create NGINX cache directories, default directories and set permissions.
mkdir /var/cache/nginx/client_temp
mkdir /var/cache/nginx/fastcgi_temp
mkdir /var/cache/nginx/proxy_temp
mkdir /var/cache/nginx/scgi_temp
mkdir /var/cache/nginx/uwsgi_temp
chmod 700 /var/cache/nginx/*
chown nginx:root /var/cache/nginx/*
mkdir /etc/nginx/conf.d
mkdir /etc/nginx/snippets
mkdir /etc/nginx/sites-available
mkdir /etc/nginx/sites-enabled
chmod 640 /var/log/nginx/*
chown nginx:root /var/log/nginx/access.log /var/log/nginx/error.log
Re-check for errors.
nginx -t
OR
service nginx configtest
Step 1.5 Enable NGINX to start on boot
First, create a systemd file.
nano /etc/systemd/system/nginx.service
Copy and paste the whole content:
[Unit]
Description=Nginx - high performance web server
Documentation=https://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
Enable the service so it will start on boot.
systemctl enable nginx.service
systemctl start nginx.service
Afterward, your web server is installed.
To check if NGINX is running, you can visit your IP address via the browser.
Open in a web browser:
How To Find Your Server’s Public IP Address
If you don’t know what your server’s public IP address is, there are many ways to find out your public IP address.
From the command line, you can use the ip
tools to get your address by typing this:
ip addr show dev eth0 | grep "inet" | awk '{ print $2 }'
Step 2 – Configure NGINX to use Brotli and Gzip
Gzip is used for browsers that don’t support Brotli.
Now, we have all of the required components installed.
Edit the NGINX configuration file and add the following lines to NGINX:
nano /etc/nginx/nginx.conf
Currently, with the comments removed, the NGINX http block looks like this:
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Find where gzip on;
is and add the following configuration:
http {
....
gzip on;
# Compression level (1-9).
gzip_comp_level 5;
# Don't compress anything that's already small
gzip_min_length 256;
# Compress data even for clients that are connecting to us via proxies
gzip_proxied any;
# Tell proxies to cache both the gzipped and regular version of a resource
# whenever the client's Accept-Encoding capabilities header varies;
gzip_vary on;
# Compress all output labeled with one of the following MIME-types.
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/vnd.ms-fontobject
application/wasm
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/otf
image/bmp
image/svg+xml
text/cache-manifest
text/calendar
text/css
text/javascript
text/markdown
text/plain
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy;
#Brotli documentation https://github.com/eustas/ngx_brotli#configuration-directives
brotli on;
#Because brotli_static is like gzip_static before it, is only for files served via nginx - it will only detect .br files when served via the filesystem
brotli_static on;
# For static files, we gonna use 11, but if there is dynamic content we should use 4(smaller response and less time to compress)
brotli_comp_level 11;
#Brotli is used only for some file types, because files like jpeg, png,mp4 are already compressed, if we use Brotli on jpeg/png, the jpeg/png is already compressed, and it will get bigger rather than smaller.
brotli_types
application/atom+xml
application/geo+json
application/javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/vnd.ms-fontobject
application/wasm
application/x-font-opentype
application/x-font-truetype
application/x-font-ttf
font/eot
font/opentype
font/otf
image/bmp
image/svg+xml
image/vnd.microsoft.icon
image/x-icon
image/x-win-bitmap
text/cache-manifest
text/css
text/javascript
text/markdown
text/plain
text/x-component
text/x-cross-domain-policy
text/xml
application/x-javascript
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
application/xml+rss;
....
}
Save and close the file.
Restart NGINX to make the necessary changes:
service nginx restart
Conclusion
If you have followed the above steps successfully, you should now have NGINX installed on your server with Brotli and Gzip compression enabled. You are now able to upload your sites files to the /var/www/html
directory and make a test with the new compression algorithms.
Reprint:https://community.hetzner.com/tutorials/install-nginx-with-brotli-and-gzip-compression-on-ubuntu
Leave a Reply