Inicio Todo lo relacionado a Internet, Programación y Tecnología

Nginx agregar soporte para Brotli en Debian y Ubuntu

nginx brotli ubuntu debian logos

En esta guía estaré explicando como compilar el módulo Brotli para Nginx, un algoritmo de compresión desarrollado por Google, como alternativa a Gzip y Deflate. La razón de compilar el módulo es que Nginx no ha dado soporte oficial a la versión de código abierto, siendo que en su versión Nginx Plus si lo tiene soportado.

El entorno usado fue Debian Buster y Ubuntu Focal con Nginx 1.14.2 y Nginx 1.18.0.

Instalar Nginx

Lo primero que necesitamos hacer es instalar Nginx. Si vamos a compilar el módulo de manera local hay que usar exactamente la misma distribución con los mismos repositorios. Ya que podemos simplemente copiarlo a producción, pero los entornos deben ser los mismos. Si en el sistema final usaremos el paquete nginx-full, nginx-extras o cualquier otro, no es mala idea instalarlos también, un pequeño detalle como este puede quitarnos muchas horas.

Instalamos con:

sudo apt -y install nginx

Instalar dependencias

Actualizamos los paquetes que tengan actualizaciones pendientes:

sudo apt update
sudo apt -y upgrade

Instalamos los siguientes paquetes:

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

Antes del siguiente paso editamos nuestro /etc/apt/sources.list, y quitamos el símbolo "#" de las líneas que tengan "deb-src", solo de los repositorios que sí se estén usando.

sudo nano /etc/apt/sources.list

En una instalación con Ubuntu viene así:

# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://archive.ubuntu.com/ubuntu focal main restricted
# deb-src http://archive.ubuntu.com/ubuntu focal main restricted

Luego de editarlo:

# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://archive.ubuntu.com/ubuntu focal main restricted
deb-src http://archive.ubuntu.com/ubuntu focal main restricted

Después actualizamos la cache de apt y de apt-src:

sudo apt update
sudo apt-src update

Descargar código fuente de Nginx y Brotli

Creamos un directorio para guardar todo:

cd ~
mkdir nginx-brotli
cd nginx-brotli

Empezamos descargando el código fuente de Nginx con apt-src para que haga juego con la versión instalada en el sistema:

sudo apt-src install nginx

Luego descargamos el código fuente de Brotli del repositorio oficial de Google:

cd ~/nginx-brotli
git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init

Compilar Brotli como módulo dinámico

Cambiamos de directorio al de Nginx:

cd ~/nginx-brotli/nginx-*/

Ejecutamos el siguiente comando para ver las opciones de compilación que la versión de Nginx instalada uso:

sudo nginx -V

Copiamos todas las opciones después del texto configure arguments:, le quitamos todas las opciones que comiencen con --add-dynamic-module y le agregamos al final separado con un espacio:

--add-dynamic-module=../ngx_brotli

Al principio le agregamos sudo ./configure y un espacio para separar las opciones. Debe ser algo similar a lo siguiente:

sudo ./configure --with-cc-opt... --with-strea... --add-dynamic-module=../ngx_brotli

El comando resultante normalmente es de varias líneas, lo resumí con las partes marcadas para que sea más comprensible. Lo ejecutamos como un comando.

Podemos usar el siguiente comando para generar el comando completo en lugar de hacerlo manualmente:

sudo nginx -V 2>&1 | grep '^configure arguments:' | sed -r 's/--add-dynamic-module=(\S)+(\s|$)//g; s/$/\-\-add\-dynamic\-module=\.\.\/ngx_brotli/g; s/configure arguments:/sudo \.\/configure/g'

El comando anterior modifica la salida de nginx -V y lo convierte en el comando que necesitamos para compilar Nginx. Lo copiamos y ejecutamos.

 

Si nos aparece el error:

./configure: error: the HTTP XSLT module requires the libxml2/libxslt

Instalamos el siguiente paquete:

sudo apt install -y libxslt1-dev

Y lo volvemos a ejecutar.

Si no aparece ningún error ejecutamos:

sudo make modules

Configuración de Nginx

Copiamos los archivos resultantes ngx_http_brotli_filter_module.so y ngx_http_brotli_static_module.so al directorio /etc/nginx/modules-available:

sudo cp objs/ngx_http_brotli_filter_module.so /etc/nginx/modules-available
sudo cp objs/ngx_http_brotli_static_module.so /etc/nginx/modules-available

Editamos el archivo /etc/nginx/nginx.conf:

sudo nano /etc/nginx/nginx.conf

Y le agregamos al principio antes de todo lo demás:

load_module /etc/nginx/modules-available/ngx_http_brotli_filter_module.so;
load_module /etc/nginx/modules-available/ngx_http_brotli_static_module.so;

Probamos la configuración y los módulos con:

sudo nginx -t

Si todo está bien nos aparecerá:

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

De lo contrario si existe algún problema la salida será:

nginx: [emerg] module ngx_http_brotli_filter_module.so is not binary compatible in nginx.conf...

Si no sabemos porque tenemos errores hay que prestar atención al comando configure y revisar al final todos los errores que aparecen. También no estaría demás revisar si estamos usando la misma versión, y en el caso de que el sistema destino sea diferente con mayor razón. Mientras no reiniciemos Nginx no habría ningún problema porque el último comando solo revisa la configuración sin realizar cambio alguno.

Para terminar con todo el desastre que quedó, eliminamos los archivos de código fuente usados:

sudo rm -R ~/nginx-brotli/

Uso en otros sistemas producción o en desarrollo

Ya que todo está comprobado y, las versiones del sistema operativo y software coinciden podemos copiar los archivos que quedaron en /etc/nginx/modules-available. Teniendo en cuenta que cada que exista una actualización por mínima que sea tenemos que recompilar los módulos para que sean compatibles. No estaría demás renombrarlos para que tengan el formato modulo-1.14-2.so haciendo referencia a la versión de Nginx para la que fueron compilados. Además de copiarlos, tenemos que realizar los pasos anteriores, como el de volver a editar el archivo de configuración de Nginx para cargar los módulos y volver a comprobar la configuración antes de reiniciar.

Bloquear actualización de paquete Nginx

Si queremos evitar accidentes podemos usar la utilidad apt-mark para forzar al gestor de paquetes a que no actualice Nginx, pero si el resto de paquetes.

Bloquear versión instalada:

sudo apt-mark hold nginx

Para desbloquear el paquete después de colocarle nuevos módulos y comprobar su configuración nueva:

sudo apt-mark unhold nginx

Reiniciar Nginx si no hay ningún problema

Para reiniciar Nginx después de comprobar que los módulos si están funcionando usar:

sudo systemctl restart nginx

Activación y uso de los módulos

Hasta este momento Nginx ya tiene cargados los módulos, solo falta activarlos y configurarlos, y al final comprobaremos si están funcionando.

Editamos el archivo nginx.conf:

nano /etc/nginx/nginx.conf

Exactamente debajo de gzip on; colocamos en una nueva línea:

brotli on;

Después buscamos una línea que tenga gzip_types, si empieza con "#" se lo quitamos, la copiamos completamente y colocamos la nueva debajo, el resultado será algo similar:

gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

Ambas líneas tienen que tener los mismos argumentos para aprovechar al máximo el nuevo algoritmo.

Comprobamos que la configuración funcione con sudo nginx -t y reiniciamos el servicio:

sudo systemctl restart nginx

Para el modulo "ngx_http_brotli_static_module.so" hay que usarlo igual que la opción gzip_static, podemos revisar la directiva en el repositorio de Google, o la directiva gzip_static en Nginx.

Comprobando funcionamiento del algoritmo de compresión

Para esto vamos a necesitar usar Firefox, Chrome, o cualquier navegador que soporte este algoritmo. En el caso que sea el mismo sistema en donde tenemos instalado el paquete, abrimos 127.0.0.1 en el navegador y abrimos las herramientas para desarrolladores con F12, y nos dirigimos a la pestaña Red o Network. Hacemos clic en la URL y verificamos que en Response Headers en Content-Encoding salga "br", en Request Headers y Accept-Encoding verificamos que salga "gzip, deflate, br" en cualquier orden. Si en Content-Encoding no aparece "br", significa que el servidor no mandó el contenido con el nuevo algoritmo, y si en Accept-Encoding no aparece "br" puede ser que el navegador no lo soporte o simplemente no se encuentra activado para el tipo de documento.

chrome developer tools brotli test

Si tenemos problemas con Firefox podría tratarse porque Brotli no está soportado en conexiones sin SSL, y como en este caso usamos localhost puede no funcionar localmente. Si queremos probar sin SSL podemos usar Chrome, este al menos en la versión 84 lo soporta sin HTTPS.

Me base en esta entrada de Website for Students, aunque tuve problemas en el paso de la compatibilidad del binario. En el repositorio oficial de Brotli viene un poco de información acerca de la compilación.

Comentarios

© 2020 ImperioWeb.net Todos los derechos reservados.