fbpx
Docker Images – Nginx & Google PageSpeed
Publicado em: segunda-feira, 12 de set de 2016
Tags: Docker | Nginx

A internet como vemos hoje exige cada vez mais performance e cada vez melhor usabilidade. Nunca tivemos tanto apreço à experiência do usuário, assim produtos, ferramentas, serviços e frameworks são bem vindos para ajudar a entregar performance. Com o aumento nos recursos de interface, e a facilidade com que conseguimos hardware, chegamos em um momento em que a renderização passa a ser um ponto chave na obtenção de performance, já que do aspecto de processamento do server, nunca vimos tanto hardware (barato), nunca vimos tantos patterns, tantas soluções para facilitar nossa vida.

Mas e quando você não tem controle sobre todo o que foi desenvolvido? Seja ao fazer deploy de um WordPress, Magento, ou soluções maiores, como SiteCore, Evoq, o que fazer quando você precisa melhorar a experiência do seu usuário? Esse problema é comum quando usamos soluções prontas, em que sua customização não necessariamente abrange detalhes tão técnicos. É sobre esse tipo de problema que quero falar e vou aproveitar para apresentar o Google PageSpeed Module for Nginx, falar um pouco sobre Nginx e como ambos podem te ajudar no seu próximo projeto.

Nginx

O nginx [engine x] é um servidor HTTP e um servidor proxy, um servidor proxy de email e um servidor proxy genérico TCP / UDP, escrito originalmente por Igor Sysoev. Por um longo tempo, ele foi executado em muitos sites russos muito acessados, incluindo Yandex, Mail.Ru, VK, e Rambler. De acordo com a Netcraft, nginx é responsável por 28,16% dos sites mais acessados do mundo, em agosto de 2016. Estão no hall de histórias de sucesso, gigantes como: Netflix, WordPress.com e FastMail.FM.

Poderoso, simples e eficiente, o Nginx ganhou espaço no mercado e sua utilização é recomendada sempre que se fala em performance e servidores HTTP.

Google PageSpeed Module for Nginx

O Google é o maior portal de busca há muitos anos. O know-how adquirido fazendo buscas e analisando milhões de sites diariamente, possibilita à gigante oferecer soluções com o que há de mais relevante sobre performance web, e o Google PageSpeed Module é um dos projetos que dá suporte ao Speed portal dedicado à otimização de performance na web. O Google PageSpeed é uma ferramenta web de análise, enquanto o Google PageSpeed Module é um projeto que oferece módulos para Nginx e Apache.

No caso do Apache, a instalação dos módulos é baseada em pacotes pré-compilados, disponíveis para download. Já no Nginx, para utilizarmos o Google PageSpeed e qualquer outro módulo, precisamos recompilar o projeto a partir dos fontes, e esse trabalho, embora simples, pode assustar muitos.

A imagem

Para facilitar a minha própria vida, criei uma imagem Docker contendo o Nginx, compilado com o Google PageSpeed no início de 2016. Essa imagem desde sua criação foi utilizada em produção, em projetos pessoais, e agora, no feriado de 7 de Setembro, resolvi parar para enfim: documentar, atualizar e publicar no GitHub o projeto.

Alguns clientes privados estão usando essa imagem com o PageSpeed ativo, usei por conta de algumas limitações, como falta de acesso aos fontes, etc. O resultado é uma camada que otimiza um site ou app mal feita. Custa processamento, mas muito pouco, dado o volume de acesso. Aconselho, para os casos em que o http server opera com mais de load elevado, utilizar uma camada de cache, que pode ser implementada habilitando caching no Nginx, ou adicionando um novo item no stack, como um CDN ou um Varnish.

Exemplo

Criando o container

Vou me basear em uma pasta hipotética “C:\_docker\nginx\”, todo o exemplo se baseará nela.

Execute o comendo docker run abaixo:

docker run --name customNginx -d --hostname customNginx -p 80:80 -v C:\_docker\nginx\config:/etc/nginx/ luizcarlosfaria/nginx-pagespeed

Agora você tem um NGINX padrão funcionando, essa versão foi compilada com os plugins que citei no início do post.

Se tudo estiver certo, você verá na pasta “C:\_docker\nginx\config\” os seguintes arquivos:

Mode                LastWriteTime         Length Name                       
----                -------------         ------ ----                       
-a----       12/09/2016     02:45           1077 fastcgi.conf               
-a----       12/09/2016     02:45           1077 fastcgi.conf.default       
-a----       12/09/2016     02:45           1007 fastcgi_params             
-a----       12/09/2016     02:45           1007 fastcgi_params.default     
-a----       12/09/2016     02:45           2837 koi-utf                    
-a----       12/09/2016     02:45           2223 koi-win                    
-a----       12/09/2016     02:45           3957 mime.types                 
-a----       12/09/2016     02:45           3957 mime.types.default         
-a----       12/09/2016     02:47           2656 nginx.conf                 
-a----       12/09/2016     02:45           2656 nginx.conf.default         
-a----       12/09/2016     02:45           2656 nginx.confx                
-a----       12/09/2016     02:45            636 scgi_params                
-a----       12/09/2016     02:45            636 scgi_params.default        
-a----       12/09/2016     02:45            664 uwsgi_params               
-a----       12/09/2016     02:45            664 uwsgi_params.default       
-a----       12/09/2016     02:45           3610 win-utf

Configurando as Transformações

Esta é a versão original das configurações. Você precisará editar o arquivo nginx.conf para prosseguir, ou caso queira, mapear uma pasta local e hospedar seus arquivos AS-IS. Mas, nosso propósito é demonstrar o Google Page Speed em ação, portanto, vamos modificar o arquivo nginx.conf por uma versão do arquivo que possui configurações exclusivas para teste da funcionalidade.

Pare o container:

docker stop customNginx

Edite o arquivo C:\_docker\nginx\config\nginx.conf substituindo todo o conteúdo por:

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    pagespeed GlobalStatisticsPath /ngx_pagespeed_global_statistics;
    pagespeed GlobalAdminPath /pagespeed_global_admin;

    server {
        listen       80;
        server_name  localhost;
        ####################################################################################################
        pagespeed on;
        # Needs to exist and be writable by nginx.  Use tmpfs for best performance.
        pagespeed FileCachePath /var/ngx_pagespeed_cache/;
        pagespeed MessagesPath /ngx_pagespeed_message;
        pagespeed ConsolePath /pagespeed_console;
        pagespeed AdminPath /pagespeed_admin;

        pagespeed StatisticsPath /pagespeed_statistics;

        # Ensure requests for pagespeed optimized resources go to the pagespeed handler
        # and no extraneous headers get set.
        location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
        add_header "" "";
        }
        location ~ "^/pagespeed_static/" { }
        location ~ "^/ngx_pagespeed_beacon$" { }        

        ####################################################################################################
        #location /ngx_pagespeed_statistics             { allow all; }
        #location /ngx_pagespeed_global_statistics     { allow all; }
        #location /ngx_pagespeed_message             { allow all; }
        #location /pagespeed_console                 { allow all; }
        #location ~ ^/pagespeed_admin                 { allow all; }
        #location ~ ^/pagespeed_global_admin         { allow all; }
        ####################################################################################################

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        #location / {
        #    root   html;
        #    index  index.html index.htm;
        #}

         location / {

            pagespeed EnableFilters move_css_to_head;
            pagespeed EnableFilters combine_javascript;
            pagespeed MaxCombinedJsBytes 999999999;
            pagespeed CombineAcrossPaths on;
            pagespeed MaxSegmentLength 2048;
            pagespeed EnableFilters responsive_images,resize_images;
            pagespeed EnableFilters responsive_images_zoom;
            pagespeed EnableFilters collapse_whitespace;
            proxy_pass      https://www.docker.com:443/;
            proxy_set_header X-Real-IP $remote_addr;
        }


    }



}

Testando e comparando

Agora execute o comando docker start para subir o container novamente, com as novas configurações carregadas:

docker start customNginx

Voilà!

Ao navegar para http://localhost/ (ou ip do seu container), você verá um proxy para https://www.docker.com/ que transforma o HTML do site.

O resultado está disponível aqui aqui.

01-docker-com-result-htmlÉ muito legal ver as transformações no html e perceber que tudo continua funcionando.

A mágica acontece graças a essa parte da configuração

...
location / {

	pagespeed EnableFilters move_css_to_head;
	pagespeed EnableFilters combine_javascript;
	pagespeed MaxCombinedJsBytes 999999999;
	pagespeed CombineAcrossPaths on;
	pagespeed MaxSegmentLength 2048;
	pagespeed EnableFilters responsive_images,resize_images;
	pagespeed EnableFilters responsive_images_zoom;
	pagespeed EnableFilters collapse_whitespace;

	proxy_pass      https://www.docker.com:443/;
	proxy_set_header X-Real-IP $remote_addr;
}
...

Nessa configuração temos algumas features utilizadas:

  • Mover CSS para o Head
  • Combinar Javascripts
  • Remover espaços em branco
  • Manipulação de imagens (resize, responsividade, zoom)

O resultado desse teste descompromissado, foi muito interessante:

  • De 9.4s para 7.9s
  • De 139 requests para 141 requests
  • De 512k transferido para 302k transferido
  • De 10.18s de load e renderização para 8.32s

01-docker-com-result

Como eu não tinha exemplos públicos para demonstrar, utilizei esse por considerar simples de demonstrar o potencial do Google Page Speed com Nginx. Vale lembrar que para o Apache, é muito mais simples, pois não há necessidade de recompilar.

A documentação do Google PageSpeed apresenta uma infinidade de opções de customização, todas baseadas no ganho de performance. É extremamente interessante olhar essa documentação para entender o que você quer ou deverá usar em seu projeto, para poder optar pelo melhor setup.

Próximas versões e Outras imagens

Penso em trabalhar na imagem para disponibilizar uma versão baseada no alpine, muito mais enxuta. Enquanto isso, essa aqui vem me atendendo perfeitamente e espero que atenda vocês também!

Há outras imagens disponíveis no hub, são elas:

Aqui no blog venho tentando apresentar esses utilitários, na medida que me sobra tempo, mas acredito que nas próximas semanas possamos falar muito mais sobre esses mecanismos.

Um grande abraço, e não se esqueça de comentar, compartilhar com a galera da empresa, enfim, é sempre bom poder ajudar.

Qualquer dúvida, não exite em entrar em contato, seja por email, twiter, telegram, whatsapp… há mil maneiras de falar comigo, e respondo todas!

Grande abraço

 

0 comentários

Enviar um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

[docker de a a z]

Lives

Fique de olho nas lives

Fique de olho nas lives no meu canal do Youtube, no Canal .NET e nos Grupos do Facebook e Instagram.

Aceleradores

Existem diversas formas de viabilizar o suporte ao teu projeto. Seja com os treinamentos, consultoria, mentorias em grupo.