Neste guia irei explicar como compilar o módulo Brotli para Nginx, um algoritmo de compressão desenvolvido pelo Google, como alternativa ao Gzip e Deflate. A razão para compilar o módulo é que o Nginx não oferece suporte oficial à versão de código aberto e em sua versão Nginx Plus é compatível.
Testado com sistemas:
- Debian 10 Buster
- Debian 11 Bullseye
- Ubuntu 20.04 Focal Fossa
- Ubuntu 22.04 LTS Jammy Jellyfish
Usando versões Nginx:
- Nginx 1.14
- Nginx 1.18
Instale o Nginx
A primeira coisa que precisamos fazer é instalar o Nginx. Se vamos compilar o módulo localmente devemos usar a mesma distribuição com os mesmos repositórios. Já que podemos simplesmente copiá-lo para produção, mas os ambientes devem ser os mesmos. Se no sistema final usaremos o pacote nginx-full, nginx-extras ou qualquer outro pacote, não é má ideia instalá-los também, um detalhe como esse pode levar muitas horas.
Instalamos com:
sudo apt -y install nginx
Instalar dependências
Atualizamos pacotes que possuem atualizações pendentes:
sudo apt update
sudo apt -y upgrade
Instalamos os seguintes pacotes:
sudo apt -y install git libpcre3 libpcre3-dev zlib1g zlib1g-dev libxslt1-dev openssl libssl-dev apt-src
Antes do próximo passo editamos nosso /etc/apt/sources.list
, e removemos o símbolo #
das linhas que possuem deb-src
, apenas dos repositórios que estão sendo usados.
sudo nano /etc/apt/sources.list
Em uma instalação do Ubuntu, os repositórios ficam assim:
deb http://archive.ubuntu.com/ubuntu focal main restricted
# deb-src http://archive.ubuntu.com/ubuntu focal main restricted
Temos que remover do comentário do cada repositório que encontramos em cada deb
. Após editá-lo deverá ficar assim:
deb http://archive.ubuntu.com/ubuntu focal main restricted
deb-src http://archive.ubuntu.com/ubuntu focal main restricted
Em seguida, atualize o cache do apt e do apt-src:
sudo apt update && sudo apt-src update
Baixe o código-fonte Nginx e Brotli
Criamos um diretório para salvar tudo no diretório inicial do nosso usuário:
cd ~ && mkdir nginx-brotli && cd nginx-brotli
Começamos baixando o código-fonte do Nginx com apt-src
para corresponder à versão instalada do sistema:
sudo apt-src install nginx
Em seguida, baixamos o código-fonte do Brotli do repositório oficial do Google:
cd ~/nginx-brotli
git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init
Compilar o Brotli como um módulo dinâmico
Mudamos o diretório para o do Nginx:
cd ~/nginx-brotli/nginx-*/
Executamos o seguinte:
sudo ./configure --with-compat --add-dynamic-module=../ngx_brotli
Se nenhum erro aparecer, executamos:
sudo make modules
E se tudo correu bem fomos para a seção Configuração do Nginx.
Em caso de erro ao usar configure
Quando obtemos um erro ao executar ./configure
acima. Seguimos os seguintes passos.
Executamos o seguinte comando para ver as opções de construção que a versão instalada do Nginx usa:
sudo nginx -V
Copiamos todas as opções após o texto configurar arguments:
, removemos todas as opções que começam com --add-dynamic-module
e as adicionamos ao final separadas por um espaço:
--add-dynamic-module=../ngx_brotli
No início adicionamos sudo ./configure
e um espaço para separar as opções. Deve ser algo semelhante ao seguinte:
sudo ./configure COMANDO_OPÇÕES --add-dynamic-module=../ngx_brotli
O comando resultante geralmente tem várias linhas, resumi-o com "COMMAND_OPTIONS" para torná-lo mais compreensível. Nós o executamos como um comando.
Podemos usar o seguinte comando para gerar o comando completo em vez de fazê-lo 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'
O comando acima modifica a saída de nginx -V
e a transforma no comando que precisamos para compilar o Nginx. Nós o copiamos e executamos.
Copie de onde diz sudo ./configure...
.
Finalmente, executamos:
sudo make modules
Configuração Nginx
Copiamos os arquivos resultantes ngx_http_brotli_filter_module.so
e ngx_http_brotli_static_module.so
para o diretório /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
Criamos o arquivo /etc/nginx/modules-enabled/50-brotli.conf
:
sudo nano /etc/nginx/modules-enabled/50-brotli.conf
E adicionamos as seguintes referências aos módulos:
load_module /etc/nginx/modules-available/ngx_http_brotli_filter_module.so;
load_module /etc/nginx/modules-available/ngx_http_brotli_static_module.so;
Testamos a configuração e os módulos com:
sudo nginx -t
Se estiver tudo bem aparecerá:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Caso contrário, se houver algum problema, a saída será:
nginx: [emerg] module ngx_http_brotli_filter_module.so is not binary compatible in nginx.conf...
Se não sabemos porque temos erros, devemos ficar atentos ao comando, configure
e revisar todos os erros que aparecem no final. Também não faria mal nenhum verificar se estamos usando a mesma versão e se o sistema de destino é diferente, ainda mais. Contanto que não reiniciemos o Nginx não haverá problema porque o último comando apenas revisa a configuração sem fazer nenhuma alteração.
Para acabar com a bagunça deixada para trás, exclua os arquivos de origem usados:
sudo rm -R ~/nginx-brotli/
Uso em outros sistemas de produção ou desenvolvimento
Como tudo está verificado e as versões do sistema operacional e do software coincidem, podemos copiar os arquivos deixados em /etc/nginx/modules-available
. Levando em consideração que toda vez que há uma atualização, por menor que seja, temos que recompilar os módulos para torná-los compatíveis. Não faria mal nenhum os renomear para terem o formato module-1.14-2.so
referindo-se à versão do Nginx para a qual foram compilados. Além de copiá-los, temos que realizar as etapas anteriores, como reeditar o arquivo de configuração do Nginx para carregar os módulos e verificar novamente a configuração antes de reiniciar.
Bloquear atualização do pacote Nginx
Se quisermos evitar acidentes, podemos usar o utilitário apt-mark para forçar o gerenciador de pacotes a não atualizar o Nginx, mas a atualizar o restante dos pacotes.
Bloquear versão instalada:
sudo apt-mark hold nginx
Para desbloquear o pacote após colocar novos módulos e verificar sua nova configuração:
sudo apt-mark unhold nginx
Reinicie o Nginx se não houver problema
Para reiniciar o Nginx após verificar se os módulos estão funcionando, use:
sudo systemctl restart nginx
Ativação e uso de módulos
Neste ponto o Nginx já está com os módulos carregados, só precisamos ativá-los e configurá-los, e ao final verificaremos se estão funcionando.
Editamos o arquivo nginx.conf
:
nano /etc/nginx/nginx.conf
Exatamente, abaixo de gzip on;
colocamos em uma nova linha:
brotli on;
Aí procuramos uma linha que tenha gzip_types
, se começar com "#" removemos, copiamos completamente e colocamos a nova abaixo dela, o resultado será algo semelhante:
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 as linhas devem ter os mesmos argumentos para aproveitar ao máximo o novo algoritmo de compressão.
Verificamos se a configuração funciona com sudo nginx -t
e reiniciamos o serviço:
sudo systemctl restart nginx
Para o módulo ngx_http_brotli_static_module.so
você deve usá-lo da mesma forma que a opção gzip_static
, podemos verificar a diretiva no repositório do Google, ou a diretiva gzip_static no Nginx.
Verificando a operação do algoritmo de compressão
Para isso precisaremos usar Firefox, Chrome ou qualquer navegador que suporte este algoritmo. Se for o mesmo sistema onde temos o pacote instalado, abrimos 127.0.0.1 no navegador e abrimos as ferramentas do desenvolvedor com F12, e vamos até a aba Rede. Clicamos na URL e verificamos se em Response Headers em Content-Encoding aparece "br", em Request Headers e Accept-Encoding verificamos se aparece "gzip, deflate, br" em qualquer ordem. Se “br” não aparecer no Content-Encoding, significa que o servidor não enviou o conteúdo com o novo algoritmo, e se “br” não aparecer no Accept-Encoding, pode ser que o navegador não suporte. Ou simplesmente não está ativado para o tipo de documento.
Se tivermos problemas com o Firefox pode ser porque o Brotli não é suportado em conexões sem SSL, e como neste caso usamos localhost ele pode não funcionar localmente. Se quisermos testar sem SSL podemos usar o Chrome, que pelo menos na versão 84 suporta sem HTTPS.
Confiei neste post do Website for Students, embora tenha tido problemas na etapa de compatibilidade binária. No repositório oficial do Brotli vem um pouco de informação sobre a build.