nginx mit Brotli-Support

Den Brotli-Kompressionsalgorithmus gibt es bereits seit ein paar Jahren und während er auch von den meisten Browsern unterstützt wird, sieht es auf der Serverseite noch nicht ganz so rosig aus. Gerade bei nginx muss man noch stark selbst Hand anlegen, um auch hier Brotli nutzen zu können. Da Brotli aber gerade bei .js- und .css-Dateien eine deutlich bessere Kompression aufweisen kann als gzip, kann die Arbeit, es bei einem Webserver zu integrieren, doch von Vorteil sein.

Um Brotli in nginx nutzen zu können, muss man leider nginx selbst kompilieren, da zur Zeit noch keine fertigen Pakete mit diesem Modul existieren. Hierfür müssen erst einmal ein paar Vorkehrungen getroffen werden. Um genau zu sein brauchen wir die nötige Software um selbst nginx kompilieren zu können.

sudo apt update
sudo apt install git dpkg-dev build-essential zlib1g-dev libpcre3 libpcre3-dev unzip brotli

Da die Version von nginx, die in den normalen Paketquellen von Debian/Ubuntu bereits etwas älter ist, fügen wir noch ein neues Repository in den Sourcen von apt ein, um mit der aktuellen Version von nginx arbeiten zu können.

curl -L https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
sudo echo deb http://nginx.org/packages/ubuntu/ bionic nginx >> /etc/apt/sources.list.d/nginx.list
sudo echo deb-src http://nginx.org/packages/ubuntu/ bionic nginx >> /etc/apt/sources.list.d/nginx.list
sudo apt-get update

Nun können wir uns den Sourcecode von nginx beschaffen, sowie alle nötigen Abhängigkeiten installieren.

cd /tmp
sudo apt source nginx
sudo apt build-dep nginx -y

Nun brauchen wir noch das Brotli-Modul für nginx. Dieses wurde von Google entwickelt, aber leider seit über zwei Jahren schon nicht mehr gepflegt. Zum Glück gibt es aber auf Github einen aktiven Fork, an dem noch gearbeitet wird.

git clone --recursive https://github.com/eustas/ngx_brotli.git

Damit nginx beim Kompilieren auch das Brotli-Modul nutzt, muss man noch eine kleine Anpassung vornehmen.

cd /tmp/nginx-*/
vim debian/rules

Hier werden nun die beiden Zeilen, startend mit config.env.nginx und config.env.nginx_debug um folgenden Eintrag am Ende ergänzt:

--add-module=/tmp/ngx_brotli

Nun kann nginx kompiliert und ein .deb-Package erzeugt werden:

cd /tmp/nginx-*/
sudo dpkg-buildpackage -b -uc -us

Im Anschluss sollten sich zwei nginx-Pakete in /tmp befinden. Diese kann man nun einfach installieren:

cd /tmp
sudo dpkg -i *.deb

Damit ist der Hauptteil der Arbeit getan und nginx unterstützt nun Brotli. Damit allerdings Websites auch zukünftig mit Brotli vor der Auslieferung mit Brotli komprimiert werden, muss man noch entsprechende Einstellungen in der Konfiguration von nginx vornehmen.

cd /etc/nginx/nginx.conf

Hier werden nun dem http-Block folgende Einträge hinzugefügt:

brotli on;
brotli_comp_level 4;
brotli_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon image/svg+xml;

Startet man den Webserver nun neu, werden automatisch die angegebenen Dateitypen mit Brotli komprimiert, bevor sie ausgeliefert werden. Hierbei sollte man aber gerade mit der Kompressionsstufe vorsichtig sein. Brotli erzeugt zwar kleinere Dateien als gzip, braucht für die Kompression aber auch mehr Ressourcen und Zeit. Daher sollte man hier durch austesten schauen, welche Kompressionsstufe den besten Mittelweg zwischen Kompressionsrate und Kompressionszeit liefert.

Wenn man nun nginx noch etwas die Arbeit abnehmen möchte, so kann man auch Elemente bereits vorher mit Brotli komprimieren. Wenn man dies abseits vom Webserver macht, bietet es den Vorteil, dass man eine höhere Kompressionsstufe verwenden kann, ohne den Webserverbetrieb zu verlangsamen. Damit nginx bereits vorhandene Brotli-Dateien verwendet, müssen diese am gleichen Ort liegen und den gleichen Namen wie ihre Originaldateien haben, sowie die Dateiendung .br haben. Aus style.css wird also style.css.br. Um dies zu nutzen, braucht die nginx-Konfiguration noch einen weiteren Eintrag:

brotli_static on;

Die statischen Brotli-Dateien haben allerdings den Nachteil, dass diese immer noch ausgeliefert werden, auch wenn sich etwas an der Website ändert. Somit bekommen Gäste immer noch einen älteren Stand ausgeliefert, was die komprimierten Dateien angeht. Wenn man dieses Feature also nutzen möchte, empfiehlt sich ein automatisches Skript, welches die Dateien in regelmäßigen Abständen überprüft und gegebenenfalls neu anlegt.