Editor – Os Dockerfiles do NGINX Plus para Alpine Linux e Debian foram atualizados em novembro de 2021 para refletir as versões mais recentes dos softwares. Eles também usam (juntamente com as instruções revisadas) segredos do Docker para transmitir informações de licença ao criar uma imagem do NGINX Plus.
Docker é uma plataforma aberta para criar, distribuir e executar aplicações distribuídas na forma de contêineres (pacotes de software leves, autônomos e executáveis que incluem tudo o que é necessário para executar uma aplicação). Por sua vez, os contêineres podem ser implantados e orquestrados por plataformas de orquestração de contêineres, como o Kubernetes. (Além da tecnologia de contêineres Docker abordada neste blog, a NGINX oferece o F5 NGINX Ingress Controller em versões baseadas no NGINX Open Source e no NGINX Plus; para assinantes do NGINX Plus, o suporte está incluído sem custo adicional.)
Como aplicações de software, NGINX Open Source e F5 NGINX Plus são excelentes casos de uso do Docker, e publicamos uma imagem do NGINX Open Source no Docker Hub, o repositório de imagens do Docker. Este post explica como:
- Implantar o NGINX Open Source usando a imagem do Docker Hub
- Gerenciar o NGINX no contêiner (conexão, configuração, registro em log, recarregamento e reinicialização)
- Implante o NGINX Plus usando uma imagem do Docker criada por você
Introdução
A plataforma aberta Docker inclui o Docker Engine — o ambiente de execução de código aberto que cria, executa e orquestra contêineres — e o Docker Hub, um serviço hospedado no qual aplicações conteinerizadas com Docker são distribuídas, compartilhadas e desenvolvidas de forma colaborativa por toda a comunidade de desenvolvimento ou dentro de uma organização específica.
Os contêineres Docker permitem que os desenvolvedores concentrem seus esforços no “conteúdo” das aplicações, separando-as das limitações da infraestrutura. As aplicações conteinerizadas com Docker podem ser transferidas instantaneamente para qualquer infraestrutura — laptop, servidor bare metal, máquina virtual ou nuvem —, tornando-se componentes modulares que podem ser facilmente combinados e recombinados em aplicações distribuídas completas e continuamente aprimorados em tempo real.
Para obter mais informações sobre o Docker, consulte Por que usar o Docker? ou a documentação completa do Docker.
Como usar a imagem Docker do NGINX Open Source
Você pode criar uma instância do NGINX em um contêiner Docker usando a imagem do NGINX Open Source do Docker Hub.
Vamos começar com um exemplo bem simples. Para iniciar uma instância do NGINX em execução em um contêiner e usando a configuração padrão do NGINX, execute este comando:
# docker run --name mynginx1 -p 80:80 -d nginxfcd1fb01b14557c7c9d991238f2558ae2704d129cf9fb97bb4fadf673a58580dEste comando cria um contêiner chamado mynginx1 com base na imagem do NGINX. O comando retorna a forma longa do ID do contêiner, que é usada no nome dos arquivos de log; consulte Gerenciamento de logs.
A opção -p instrui o Docker a mapear a porta exposta no contêiner pela imagem do NGINX – porta 80 – para a porta especificada no host do Docker. O primeiro parâmetro especifica a porta no host do Docker, enquanto o segundo parâmetro é mapeado para a porta exposta no contêiner.
A opção -d especifica que o contêiner seja executado no modo desanexado, o que significa que ele continuará em execução até ser interrompido, mas não responderá aos comandos executados na linha de comando. Na próxima seção, explicamos como interagir com o contêiner.
Para verificar se o contêiner foi criado e está em execução, e para ver os mapeamentos de portas, executamos docker ps. (Dividimos a saída em várias linhas aqui para facilitar a leitura.)
# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS ...
fcd1fb01b145 nginx:latest "nginx -g 'daemon of 16 seconds ago Up 15 seconds ...
... PORTS NAMES
... 0.0.0.0:80->80/tcp mynginx1O campo PORTS na saída informa que a porta 80 no host do Docker está mapeada para a porta 80 no contêiner. Outra maneira de verificar se o NGINX está em execução é fazer uma solicitação HTTP para essa porta. O código da página de boas-vindas padrão do NGINX é exibido:
# curl http://localhost<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="https://www.nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>Trabalhando com o contêiner Docker do NGINX
Agora temos um contêiner Docker do NGINX funcionando, mas como gerenciamos o conteúdo e a configuração do NGINX? E quanto aos logs?
Uma observação sobre SSH
É comum habilitar o acesso via SSH às instâncias do NGINX, mas a imagem do NGINX não tem o OpenSSH instalado, pois os contêineres Docker geralmente são destinados a uma única finalidade (neste caso, executar o NGINX). Em vez disso, usaremos outros métodos compatíveis com o Docker.
Como alternativa aos comandos a seguir, você pode executar o comando abaixo para abrir um shell interativo em um contêiner NGINX em execução (em vez de iniciar uma sessão SSH). No entanto, recomendamos essa opção apenas para usuários avançados.
- Em sistemas Alpine Linux:
# docker exec -it NGINX_container_ID sh- Em sistemas Debian:
# docker exec -it NGINX_container_ID bashGerenciando arquivos de conteúdo e configuração
Há várias maneiras de gerenciar tanto o conteúdo disponibilizado pelo NGINX quanto os arquivos de configuração do NGINX. Aqui, abordamos algumas dessas opções.
Opção 1 – Manter o conteúdo e a configuração no host do Docker
Ao criar o contêiner, podemos instruir o Docker a montar um diretório local do host Docker em um diretório no contêiner. A imagem do NGINX usa a configuração padrão do NGINX, que define /usr/share/nginx/html como o diretório raiz do contêiner e armazena os arquivos de configuração em /etc/nginx. Para um host Docker com conteúdo no diretório local /var/www e arquivos de configuração em /var/nginx/conf, execute este comando (que aparece em várias linhas aqui apenas para facilitar a leitura):
# docker run --name mynginx2 --mount type=bind source=/var/www,target=/usr/share/nginx/html,readonly --mount type=bind,source=/var/nginx/conf,target=/etc/nginx/conf,readonly -p 80:80 -d nginxAgora, qualquer alteração feita nos arquivos dos diretórios locais /var/www e /var/nginx/conf no host Docker é refletida nos diretórios /usr/share/nginx/html e /etc/nginx do contêiner. A opção readonly significa que esses diretórios só podem ser alterados no host Docker, e não de dentro do contêiner.
Opção 2 – Copiar arquivos do host do Docker
Outra opção é fazer com que o Docker copie os arquivos de conteúdo e configuração de um diretório local no host do Docker durante a criação do contêiner. Depois que um contêiner é criado, os arquivos são mantidos criando um novo contêiner quando eles são alterados ou modificando os arquivos no contêiner. Uma maneira simples de copiar os arquivos é criar um Dockerfile com comandos que são executados durante a geração de uma nova imagem do Docker baseada na imagem do NGINX do Docker Hub. Para os comandos de cópia de arquivos (COPY) no Dockerfile, o caminho do diretório local é relativo ao contexto de compilação em que o Dockerfile está localizado.
Em nosso exemplo, o conteúdo está no diretório content e os arquivos de configuração estão no diretório conf, ambos subdiretórios do diretório em que o Dockerfile está localizado. A imagem do NGINX inclui arquivos de configuração padrão do NGINX em /etc/nginx/nginx.conf e /etc/nginx/conf.d/default.conf. Como queremos usar os arquivos de configuração do host, incluímos um comando RUN que exclui os arquivos padrão:
FROM nginx
RUN rm /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY content /usr/share/nginx/html
COPY conf /etc/nginxCriamos nossa própria imagem do NGINX executando o comando a seguir no diretório em que o Dockerfile está localizado. Observe o ponto (“.”) no final do comando. Ele define o diretório atual como o contexto de build, que contém o Dockerfile e os diretórios que serão copiados.
# docker build -t mynginx_image1 .Agora, executamos este comando para criar um contêiner chamado mynginx3 com base na imagem mynginx_image1:
# docker run --name mynginx3 -p 80:80 -d mynginx_image1Se quisermos fazer alterações nos arquivos do contêiner, usamos um contêiner auxiliar, conforme descrito na Opção 3.
Opção 3 – Manter arquivos no contêiner
Conforme mencionado em Uma observação sobre SSH, não podemos usar SSH para acessar o contêiner do NGINX. Portanto, se quisermos editar diretamente os arquivos de conteúdo ou de configuração, teremos que criar um contêiner auxiliar com acesso ao shell. Para que o contêiner auxiliar tenha acesso aos arquivos, precisamos criar uma nova imagem que tenha os volumes de dados do Docker apropriados definidos. Supondo que queiramos copiar arquivos como na Opção 2 e também definir volumes, usamos o seguinte Dockerfile:
FROM nginxRUN rm /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY content /usr/share/nginx/html
COPY conf /etc/nginx
VOLUME /usr/share/nginx/html
VOLUME /etc/nginxEm seguida, criamos a nova imagem do NGINX executando o seguinte comando (novamente, observe o ponto final):
# docker build -t mynginx_image2 .Agora, executamos este comando para criar um contêiner NGINX (mynginx4) baseado na imagem mynginx_image2:
# docker run --name mynginx4 -p 80:80 -d mynginx_image2Em seguida, executamos o comando a seguir para iniciar um contêiner auxiliar chamado mynginx4_files, que possui um shell e nos permite acessar os diretórios de conteúdo e configuração do contêiner mynginx4 que acabamos de criar:
# docker run -i -t --volumes-from mynginx4 --name mynginx4_files debian /bin/bashroot@b1cbbad63dd1:/#O novo contêiner auxiliar mynginx4_files é executado em primeiro plano com uma entrada padrão persistente (a opção -i) e um tty (a opção -t). Todos os volumes definidos em mynginx4 são montados como diretórios locais no contêiner auxiliar.
O argumento debian indica que o contêiner auxiliar usa a imagem do Debian do Docker Hub. Como a imagem do NGINX também usa o Debian (e todos os nossos exemplos até agora usam a imagem do NGINX), é mais eficiente usar o Debian no contêiner auxiliar, em vez de fazer com que o Docker carregue outro sistema operacional. O argumento /bin/bash indica que o shell bash é executado no contêiner auxiliar, exibindo um prompt de shell que você pode usar para modificar arquivos conforme necessário.
Para iniciar e parar o contêiner, execute os seguintes comandos:
# docker start mynginx4_files# docker stop mynginx4_filesPara sair do shell sem interromper a execução do contêiner, pressione Ctrl+p e, em seguida, Ctrl+q. Para acessar novamente o shell de um contêiner em execução, execute este comando:
# docker attach mynginx4_filesPara sair do shell e encerrar o contêiner, execute o comando exit.
Gerenciando logs
Você pode configurar o registro em log padrão ou personalizado.
Como usar o registro em log padrão
Por padrão, a imagem do NGINX é configurada para enviar os principais logs de acesso e de erros do NGINX ao coletor de logs do Docker. Isso é feito vinculando-os, respectivamente, a stdout e stderr; todas as mensagens de ambos os logs são então gravadas no arquivo /var/lib/docker/containers/container-ID/container-ID-json.log no host do Docker, em que container‑ID é o ID completo retornado quando você cria um contêiner. Por exemplo, para o contêiner inicial que criamos em Como usar a imagem Docker do NGINX Open Source, o ID é fcd1fb01b14557c7c9d991238f2558ae2704d129cf9fb97bb4fadf673a58580d.
Para obter o ID de um contêiner existente, execute este comando, em que container‑name é o valor definido pelo parâmetro --name quando o contêiner é criado (para o ID de contêiner acima, por exemplo, esse valor é mynginx1):
# docker inspect --format '{{ .Id }}' container-nameEmbora seja possível visualizar os logs abrindo diretamente o arquivo container-ID-json.log, geralmente é mais fácil executar este comando:
# docker logs container-nameVocê também pode usar a API do Docker Engine para extrair as mensagens de log, enviando uma solicitação GET ao socket Unix do Docker. Esse comando retorna tanto o log de acesso (representado por stdout=1) quanto o log de erros (stderr=1), mas você também pode solicitá-los separadamente:
curl --unix-socket /var/run/docker-sock http://localhost/containers/container-name/logs?stdout=1&stderr=1Para saber mais sobre outros parâmetros de consulta, consulte a documentação da API do Docker Engine (pesquise por “Get container logs” nessa página).
Como usar logs personalizados
Se você quiser implementar outro método de coleta de logs ou configurar o registro em log de forma diferente em determinados blocos de configuração (como server{} e location{}), defina um volume do Docker para o diretório ou os diretórios nos quais os arquivos de log serão armazenados no contêiner, crie um contêiner auxiliar para acessar esses arquivos e use as ferramentas de registro em log que preferir. Para implementar isso, crie uma nova imagem que contenha o volume ou os volumes destinados aos arquivos de log.
Por exemplo, para configurar o NGINX para armazenar os arquivos de log em /var/log/nginx/log, podemos começar com o Dockerfile da Opção 3 e simplesmente adicionar uma definição de VOLUME para esse diretório:
FROM nginxRUN rm /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY content /usr/share/nginx/html
COPY conf /etc/nginx
VOLUME /var/log/nginx/logEm seguida, podemos criar uma imagem conforme descrito acima e usá-la para criar um contêiner NGINX e um contêiner auxiliar que tenham acesso ao diretório de logs. O contêiner auxiliar pode ter quaisquer ferramentas de registro desejadas instaladas.
Controlando o NGINX
Como não temos acesso direto à linha de comando do contêiner NGINX, não podemos usar o comando nginx para controlar o NGINX. Felizmente, podemos usar sinais para controlar o NGINX, e o Docker fornece o comando kill para enviar sinais a um contêiner.
Para recarregar a configuração do NGINX, execute este comando:
# docker kill -s HUP container-namePara reiniciar o NGINX, execute este comando para reiniciar o contêiner:
# docker restart container-nameImplantando o NGINX Plus com o Docker
Até agora, discutimos o uso do Docker com o NGINX Open Source, mas você também pode usá-lo com o produto comercial NGINX Plus. A diferença é que primeiro você precisa criar uma imagem do NGINX Plus, pois, por ser uma oferta comercial, o NGINX Plus não está disponível no Docker Hub. Felizmente, isso é bastante fácil de fazer.
Observação: Nunca envie suas imagens do NGINX Plus para um repositório público, como o Docker Hub. Isso viola seu contrato de licença.
Como criar uma imagem Docker do NGINX Plus
Para gerar uma imagem do NGINX Plus, primeiro crie um Dockerfile. Os exemplos apresentados aqui usam o Alpine Linux 3.14 e o Debian 11 (Bullseye) como imagens base do Docker. Antes de criar a imagem do NGINX Plus para Docker, você precisa baixar a sua versão dos arquivos nginx-repo.crt e nginx-repo.key. Os clientes do NGINX Plus podem encontrá-los no portal do cliente; se você estiver fazendo uma avaliação gratuita do NGINX Plus, esses arquivos foram fornecidos com o seu pacote de avaliação. Copie os arquivos para o diretório onde o Dockerfile está localizado (o contexto de build do Docker).
Assim como no NGINX Open Source, por padrão, os logs de acesso e de erros do NGINX Plus são vinculados ao coletor de logs do Docker. Nenhum volume é especificado, mas você pode adicioná-los se desejar, ou cada Dockerfile pode ser usado para criar imagens base a partir das quais você pode criar novas imagens com volumes especificados, conforme descrito anteriormente.
Intencionalmente, não especificamos uma versão do NGINX Plus nos exemplos de Dockerfiles, para que você não precise editar o arquivo ao atualizar para uma nova versão do NGINX Plus. No entanto, incluímos versões comentadas das instruções relevantes, que você pode descomentar caso queira tornar o arquivo específico para uma determinada versão.
Da mesma forma, incluímos instruções (comentadas) que instalam módulos dinâmicos oficiais para o NGINX Plus.
Por padrão, nenhum arquivo é copiado do host do Docker durante a criação de um contêiner. Você pode adicionar definições COPY a cada Dockerfile, ou a imagem criada pode ser usada como base para outra imagem, conforme descrito acima.
Dockerfile do NGINX Plus (Debian 11)
Carregando exemplo de código…
Dockerfile do NGINX Plus (Alpine Linux 3.14)
Carregando exemplo de código…
Criando a imagem do NGINX Plus
Com o Dockerfile, o nginx-repo.crt e o nginx-repo.key no mesmo diretório, execute nele o comando a seguir para criar uma imagem do Docker chamada nginxplus (como antes, observe o ponto final):
# DOCKER_BUILDKIT=1 docker build --no-cache -t nginxplus --secret id=nginx-crt,src=your_cert_file --secret id=nginx-key,src=your_key_file .A flag DOCKER_BUILDKIT=1 indica que estamos usando o Docker BuildKit para criar a imagem, conforme necessário ao incluir a opção --secret, abordada abaixo.
A opção --no-cache instrui o Docker a criar a imagem do zero e garante a instalação da versão mais recente do NGINX Plus. Se o Dockerfile tiver sido usado anteriormente para criar uma imagem e você não incluir a opção --no-cache, a nova imagem usará a versão do NGINX Plus armazenada no cache do Docker. (Como mencionado, propositalmente não especificamos uma versão do NGINX Plus no Dockerfile para que o arquivo não precise ser alterado a cada nova versão do NGINX Plus.) Omita a opção --no-cache se for aceitável usar a versão do NGINX Plus da imagem criada anteriormente.
A opção --secret passa o certificado e a chave da sua licença do NGINX Plus para o contexto de build do Docker sem o risco de expor os dados ou de mantê-los entre as camadas de build do Docker. Os valores dos argumentos id não podem ser alterados sem modificar o Dockerfile base, mas você precisa definir os argumentos src como o caminho para os arquivos de certificado e chave do NGINX Plus (o mesmo diretório em que você está criando a imagem do Docker, caso tenha seguido as instruções anteriores).
Uma saída como a seguinte do comando docker images nginxplus indica que a imagem foi criada com sucesso:
# docker images nginxplus
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
nginxplus latest ef2bf65931cf 6 seconds ago 91.2 MBPara criar um contêiner chamado mynginxplus com base nessa imagem, execute este comando:
# docker run --name mynginxplus -p 80:80 -d nginxplusVocê pode controlar e gerenciar contêineres do NGINX Plus da mesma forma que os contêineres do NGINX Open Source.
Resumo
NGINX, NGINX Plus e Docker funcionam extremamente bem em conjunto. Seja usando a imagem do NGINX Open Source do Docker Hub ou criando sua própria imagem do NGINX Plus, você pode facilmente iniciar novas instâncias do NGINX e do NGINX Plus em contêineres Docker e implantá-las em seu ambiente Kubernetes. Você também pode criar facilmente novas imagens Docker a partir das imagens base, facilitando ainda mais o controle e o gerenciamento dos seus contêineres. Certifique-se de que todas as instâncias do NGINX Plus em execução nos seus contêineres Docker estejam cobertas pela sua assinatura. Para obter mais informações, entre em contato com a equipe de vendas da NGINX.
Há muito mais sobre o Docker do que foi possível abordar neste artigo. Para saber mais, baixe gratuitamente nosso e-book da O’Reilly – Redes de contêineres: do Docker ao Kubernetes – ou acesse www.docker.com.
Documentação relacionada
Implantação do NGINX e do NGINX Plus no Docker
Sobre o autor

Publicações relacionadas no blog

Como o F5 NGINX One aprimora o gerenciamento e a observabilidade
Descubra como o F5 NGINX One aprimora o gerenciamento e a observabilidade de ambientes híbridos e multicloud ao oferecer um console web centralizado baseado em SaaS, com insights em tempo real, conformidade automatizada e gerenciamento simplificado de configurações.

Do OpenAPI ao NGINX como gateway de API usando uma API declarativa
Descubra como transformar uma definição de esquema OpenAPI em uma configuração NGINX totalmente funcional, operando como um API Gateway com a segurança de um Web Application Firewall e um Portal do Desenvolvedor, usando uma abordagem declarativa de API.

Como gerenciar picos repentinos de tráfego e sobrecarga do servidor
Picos de tráfego e sobrecarga de servidores são preocupações sérias para varejistas online em qualquer época, mas especialmente durante a “Cyber Season” de compras de fim de ano. Detalhamos como você pode aproveitar as soluções de entrega de aplicações de nível de produção da NGINX para se preparar para aumentos repentinos de tráfego.

Distribuição segura de chaves privadas SSL com o NGINX
Descrevemos três maneiras progressivamente mais seguras de proteger chaves privadas SSL ao configurar o NGINX para processar tráfego HTTPS: permitir acesso de leitura apenas ao usuário root, criptografar as chaves com senhas armazenadas separadamente e distribuir as senhas a partir de um repositório central.
Agrupando solicitações de API em lotes com NGINX Plus e o módulo JavaScript do NGINX
O módulo JavaScript do NGINX lançado com o NGINX Plus R15 oferece suporte a subsolicitações, possibilitando uma classe totalmente nova de casos de uso para o NGINX Plus. Este exemplo completo também usa a API do NGINX Plus e os módulos de chave-valor para converter solicitações de API dos clientes em solicitações separadas para as APIs dos microsserviços que compõem um aplicativo.
Como superar o esgotamento de portas efêmeras no NGINX e no NGINX Plus
Confira dicas para evitar o esgotamento de portas efêmeras com ajustes no kernel do Linux, conexões keepalive e conexões vinculadas dinamicamente a endereços IP locais.