Docker explicado: como conteinerizar e usar o Nginx como um proxy
Status: Obsoleto
Este artigo está obsoleto e não é mais mantido.
Razão
As técnicas neste artigo estão desatualizadas e podem não refletir mais as práticas recomendadas do Docker.
Ver em vez disso
- O ecossistema Docker: uma introdução aos componentes comuns
- Como executar o Nginx em um contêiner Docker no Ubuntu 14.04
Introdução
Quando se trata de lidar com solicitações para servidores de aplicativos da Web e servir conteúdo estático, o Nginx, testado e comprovado, é uma escolha extremamente popular hoje em dia. À medida que você trabalha com o docker e conteineriza seus aplicativos, ter o Nginx servindo-os também faz sentido na maioria das situações. Afinal, esses contêineres permitem portar aplicativos facilmente, dimensionar rapidamente e adicionar outra camada à segurança do seu host (ou seja, droplets).
Neste artigo da DigitalOcean, aprenderemos como configurar rapidamente o docker, criar um contêiner docker a partir de uma imagem base e construí-lo para executar o Nginx camada por camada. Depois, seguindo nossos passos desde o início, vamos criar um Dockerfile para automatizar todo esse processo. No final, usando esta imagem do docker do Nginx, você poderá criar sandboxes independentes executando o Nginx, que podem ser usados para servir seus aplicativos dockerizados.
Glossário
1. Resumo do Docker
2. Resumo do Nginx
3. Instalando o Docker no Ubuntu
4. Comandos básicos do Docker
- Executando o daemon do docker e o uso da CLI
- Comandos do Docker
5. Construindo um Docker Container com o Nginx instalado
- Criando um contêiner base do Docker a partir do Ubuntu
- Preparando o contêiner base para instalação do Nginx
- Instalando o Nginx
- Configurando o Nginx
6. Criando o Dockerfile para construir a imagem automaticamente
- Noções básicas do Dockerfile
- Visão geral dos comandos do Dockerfile
- Criando o Dockerfile
- Definindo os fundamentos
- Instruções de instalação para Nginx
- Bootstrapping
- Final Dockerfile
- Usando o Dockerfile para criar contêineres Nginx automaticamente
Resumo do Docker
O projeto docker oferece ferramentas de alto nível, trabalhando juntas, que são construídas sobre alguns recursos do kernel do Linux. O objetivo é ajudar desenvolvedores e administradores de sistema a portar aplicativos - com todas as suas dependências em conjunto - e colocá-los em execução em sistemas e máquinas - sem dor de cabeça.
O Docker consegue isso criando ambientes seguros baseados em LXC (ou seja, Linux Containers) para aplicativos chamados contêineres docker. Esses contêineres são criados usando imagens docker, que podem ser construídas executando comandos manualmente ou automaticamente por meio de Dockerfiles.
Observação: para saber mais sobre o docker e suas partes (por exemplo, daemon docker, CLI, imagens etc.), confira nosso artigo introdutório ao projeto: docker Explained: Getting Started.
Nginx em resumo
Nginx é um servidor web de alto desempenho/proxy (reverso). Ele alcançou sua popularidade por ser leve, relativamente fácil de trabalhar e fácil de estender (com add-ons/plug-ins). Graças à sua arquitetura, ele é capaz de lidar com muitas solicitações (praticamente ilimitadas), que - dependendo do carregamento do aplicativo ou do site - podem ser muito difíceis de resolver usando alternativas mais antigas. Pode ser considerada a ferramenta a ser escolhida para servir arquivos estáticos como imagens, scripts ou folhas de estilo.
Instalando o Docker no Ubuntu (mais recente)
Com seu lançamento mais recente (0.7.1. datado de 5 de dezembro), o docker pode ser implantado em vários sistemas operacionais Linux, incluindo Ubuntu/Debian e CentOS/RHEL.
Lembre-se de que você pode começar rapidamente usando a imagem docker pronta para uso da DigitalOcean construída no Ubuntu 13.04.
Passaremos rapidamente pelo processo de instalação do Ubuntu (mais recente).
Instruções de instalação para Ubuntu
Atualize seu droplet:
sudo aptitude update
sudo aptitude -y upgrade
Verifique se o suporte aufs está disponível:
sudo aptitude install linux-image-extra-`uname -r`
Adicione a chave do repositório docker ao apt-key para verificação do pacote:
sudo sh -c "wget -qO- https://get.docker.io/gpg | apt-key add -"
Adicione o repositório docker às fontes do aptitude:
sudo sh -c "echo deb http://get.docker.io/ubuntu docker main\
> /etc/apt/sources.list.d/docker.list"
Atualize o repositório com a nova adição:
sudo aptitude update
Finalmente, baixe e instale o docker:
sudo aptitude install lxc-docker
O firewall padrão do Ubuntu (UFW: Uncomplicated Firewall) nega todo o tráfego de encaminhamento por padrão, o que é necessário para o docker.
Habilite o encaminhamento com UFW:
Edite a configuração do UFW usando o editor de texto nano.
sudo nano /etc/default/ufw
Role para baixo e localize a linha que começa com DEFAULT_FORWARD_POLICY.
Substituir:
DEFAULT_FORWARD_POLICY="DROP"
Com:
DEFAULT_FORWARD_POLICY="ACCEPT"
Pressione CTRL+X e aprove com Y para salvar e fechar.
Finalmente, recarregue o UFW:
sudo ufw reload
Comandos básicos do Docker
Antes de começarmos a trabalhar com o docker, vamos examinar rapidamente os comandos disponíveis para refrescar nossa memória do nosso primeiro artigo Introdução.
Executando o daemon do docker e o uso da CLI
Após a instalação, o daemon do docker deve estar em execução em segundo plano, pronto para aceitar comandos enviados pela CLI do docker. Para determinadas situações em que pode ser necessário executar manualmente o docker, use o seguinte:
Executando o daemon do docker:
sudo docker -d &
Uso da CLI do docker:
sudo docker [option] [command] [arguments]
Nota: o docker precisa de privilégios sudo para funcionar.
Comandos do Docker
Aqui está um resumo dos comandos docker atualmente disponíveis (versão 0.7.1):
attach: Attach to a running container
build: Build a container from a Dockerfile
commit: Create a new image from a container's changes
cp: Copy files/folders from the containers filesystem to the host path
diff: Inspect changes on a container's filesystem
events: Get real time events from the server
export: Stream the contents of a container as a tar archive
history: Show the history of an image
images: List images
import: Create a new filesystem image from the contents of a tarball
info: Display system-wide information
insert: Insert a file in an image
inspect: Return low-level information on a container
kill: Kill a running container
load: Load an image from a tar archive
login: Register or Login to the docker registry server
logs: Fetch the logs of a container
port: Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
ps: List containers
pull: Pull an image or a repository from the docker registry server
push: Push an image or a repository to the docker registry server
restart: Restart a running container
rm: Remove one or more containers
rmi: Remove one or more images
run: Run a command in a new container
save: Save an image to a tar archive
search: Search for an image in the docker index
start: Start a stopped container
stop: Stop a running container
tag: Tag an image into a repository
top: Lookup the running processes of a container
version: Show the docker version information
Vamos começar!
===
Construindo um Docker Container com o Nginx instalado
Depois de instalar o docker em nosso VPS e revisar rapidamente seus comandos, estamos prontos para começar com o trabalho real para criar nosso contêiner docker executando o Nginx.
Nota: Embora depois de seguir esta seção teremos um contêiner docker em execução com o Nginx instalado, definitivamente não é o método recomendado devido à sua complexidade. No entanto, está aqui para oferecer a você a chance de aprender a trabalhar com um contêiner ativo e se familiarizar com os comandos que precisaremos definir posteriormente para automatizar o processo. Para criar uma imagem docker com o Nginx instalado de uma maneira muito melhor, consulte a próxima seção: Criando um Dockerfile para construir automaticamente a imagem do Nginx.
Criando um contêiner base do Docker no Ubuntu
Usando o comando RUN do docker, começaremos criando um novo contêiner baseado na imagem do Ubuntu. Vamos anexar um terminal a ele usando o sinalizador \-t.
sudo docker run -i -t -p 80:80 ubuntu /bin/bash
Observação: depois de executar este comando, o docker pode precisar puxar a imagem do Ubuntu antes de criar um novo contêiner para você.
Lembre-se: você será anexado ao contêiner que criar. Para se desconectar e voltar ao ponto de acesso do terminal principal, execute a sequência de escape: CTRL+P seguido de CTRL+Q. Estar conectado a um contêiner docker é como estar conectado a um novo droplet de dentro de outro.
Para se conectar de volta a este contêiner:
- Liste todos os contêineres em execução usando sudo docker ps
- Encontre seu ID
- Use sudo docker attach [id] para anexar de volta ao seu terminal
Importante: Não esqueça que como estamos em um container, todos os comandos a seguir serão executados ali, sem afetar o host.
Preparando o contêiner base para a instalação do Nginx
Para instalar o Nginx e as ferramentas necessárias para o processo, o repositório do aplicativo relevante deve estar disponível para download.
Vamos anexar o universo do Ubuntu à lista padrão da imagem base.
echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
Atualize a lista com a fonte recém-adicionada.
apt-get update
Antes de prosseguirmos com a instalação do Nginx, existem algumas ferramentas que devemos instalar, como o nano - apenas por precaução.
apt-get install -y nano \
wget \
dialog \
net-tools
Instalando o Nginx
Graças a tê-lo disponível no repositório, podemos simplesmente usar o apt-get para baixar e instalar o nginx.
apt-get install -y nginx
Configurando o Nginx
Usando o editor de texto nano, que instalamos na etapa anterior, vamos criar um exemplo de configuração Nginx para conexões de proxy para servidores de aplicativos.
# Delete the default configuration
rm -v /etc/nginx/nginx.conf
# Create a blank one using nano text editor
nano /etc/nginx/nginx.conf
Primeiro, no topo do arquivo, uma linha deve ser adicionada para não fazer com que o Nginx gere seus processos e saia.
A razão pela qual não podemos permitir que isso aconteça é porque o docker depende de um único processo para ser executado (que pode até ser um gerenciador de processos) e quando esse processo para (ou seja, encerra após a geração de trabalhadores), o contêiner para.
Comece com o seguinte como a primeira linha do nginx.conf
:
daemon off;
Usaremos uma configuração de exemplo simples para que o Nginx seja executado como um proxy reverso. Copie e cole o seguinte após a instrução daemon off;
.
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
gzip on;
gzip_http_version 1.0;
gzip_proxied any;
gzip_min_length 500;
gzip_disable "MSIE [1-6]\.";
gzip_types text/plain text/xml text/css
text/comma-separated-values
text/javascript
application/x-javascript
application/atom+xml;
# List of application servers
upstream app_servers {
server 127.0.0.1:8080;
}
# Configuration for the server
server {
# Running port
listen 80;
# Proxying the connections connections
location / {
proxy_pass http://app_servers;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}
Salve e saia pressionando CTRL+X e confirmando com Y.
Para executar o Nginx, você pode executar o seguinte:
service nginx start
E é isso! Agora temos o Nginx rodando em um contêiner docker, acessível do mundo externo na porta 80 conforme definimos usando o sinalizador -p 80:80
.
Lembre-se: Este arquivo Nginx, embora configurado corretamente, não fará nada, pois atualmente não há servidores de aplicativos em execução no servidor. Em vez deste, você pode copiar e usar outro exemplo que simplesmente funciona como um proxy de encaminhamento para testar cabeçalhos HTTP até que você tenha seu(s) servidor(es) de aplicativos instalado(s) e funcionando.
Criando o Dockerfile para construir a imagem automaticamente
Como mencionamos na etapa anterior, certamente não é a maneira recomendada de criar contêineres dessa maneira para produção escalável. A maneira certa de fazer pode ser considerada como usar Dockerfiles para automatizar o processo de construção de forma estruturada.
Depois de passar pelos comandos necessários para baixar e instalar o Nginx dentro de um contêiner, podemos usar o mesmo conhecimento para compor um Dockerfile que o docker pode usar para criar uma imagem, que pode ser usada para executar instâncias do Nginx facilmente.
Antes de começarmos a trabalhar no Dockerfile, vamos examinar rapidamente o básico.
Noções básicas do Dockerfile
Dockerfiles são scripts contendo comandos declarados sucessivamente que devem ser executados nessa ordem pelo docker para criar automaticamente uma nova imagem docker. Eles ajudam muito nas implantações.
Esses arquivos sempre começam com a definição de uma imagem base usando o comando FROM
. A partir daí, o processo de construção começa e cada ação seguinte forma a imagem final que será confirmada no host.
Uso:
# Build an image using the Dockerfile at current location
# Tag the final image with [name] (e.g. *nginx*)
# Example: sudo docker build -t [name] .
sudo docker build -t nginx_img .
Observação: para saber mais sobre Dockerfiles, confira nosso artigo: Explicação do Docker: usando Dockerfiles para automatizar a construção de imagens.
Visão geral dos comandos do Dockerfile
- ADD: Copie um arquivo do host para o contêiner
- CMD: Define os comandos padrão a serem executados ou passados para o ENTRYPOINT
- ENTRYPOINT: Defina o aplicativo de ponto de entrada padrão dentro do contêiner
- ENV: Defina a variável de ambiente (por exemplo, chave=valor)
- EXPOSE: Expor uma porta para fora
- DE: Defina a imagem base a ser usada
- MAINTAINER: Defina os dados do autor/proprietário do Dockerfile
- RUN: Executa um comando e confirma a imagem do resultado final (contêiner)
- USER: Defina o usuário para executar os contêineres da imagem
- VOLUME: Monte um diretório do host para o contêiner
- WORKDIR: Defina o diretório para as diretivas do CMD a serem executadas
Criando o Dockerfile
Para criar um Dockerfile no local atual usando o editor de texto nano, execute o seguinte comando:
sudo nano Dockerfile
Nota: Anexe todas as linhas a seguir uma após a outra para formar o Dockerfile a ser salvo e usado para construção.
Definindo os fundamentos
Vamos começar nosso Dockerfile definindo o básico (fundamentos), como a imagem FROM
(ou seja, Ubuntu) e o MAINTAINER
.
############################################################
# Dockerfile to build Nginx Installed Containers
# Based on Ubuntu
############################################################
# Set the base image to Ubuntu
FROM ubuntu
# File Author / Maintainer
MAINTAINER Maintaner Name
Instruções de instalação para Nginx
Seguindo nossos passos da seção anterior, vamos formar o bloco para ter o Nginx instalado.
# Install Nginx
# Add application repository URL to the default sources
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
# Update the repository
RUN apt-get update
# Install necessary tools
RUN apt-get install -y nano wget dialog net-tools
# Download and Install Nginx
RUN apt-get install -y nginx
Bootstrapping
Depois de adicionar as instruções para instalar o Nginx, vamos terminar com a configuração do Nginx e obter o Dockerfile para substituir o arquivo de configuração padrão por um que fornecemos durante a compilação.
# Remove the default Nginx configuration file
RUN rm -v /etc/nginx/nginx.conf
# Copy a configuration file from the current directory
ADD nginx.conf /etc/nginx/
# Append "daemon off;" to the beginning of the configuration
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# Expose ports
EXPOSE 80
# Set the default command to execute
# when creating a new container
CMD service nginx start
Dockerfile final
No final, é assim que o Dockerfile deve ficar:
############################################################
# Dockerfile to build Nginx Installed Containers
# Based on Ubuntu
############################################################
# Set the base image to Ubuntu
FROM ubuntu
# File Author / Maintainer
MAINTAINER Maintaner Name
# Install Nginx
# Add application repository URL to the default sources
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
# Update the repository
RUN apt-get update
# Install necessary tools
RUN apt-get install -y nano wget dialog net-tools
# Download and Install Nginx
RUN apt-get install -y nginx
# Remove the default Nginx configuration file
RUN rm -v /etc/nginx/nginx.conf
# Copy a configuration file from the current directory
ADD nginx.conf /etc/nginx/
# Append "daemon off;" to the beginning of the configuration
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# Expose ports
EXPOSE 80
# Set the default command to execute
# when creating a new container
CMD service nginx start
Novamente salve e saia do arquivo pressionando CTRL+X e confirmando com Y.
Usando o Dockerfile para construir contêineres Nginx automaticamente
Como examinamos pela primeira vez na seção básicos, o uso dos Dockerfiles consiste em chamá-los com o comando docker build.
Como estamos instruindo o docker a copiar uma configuração (ou seja, nginx.conf) do diretório atual para substituir o padrão, precisamos ter certeza de tê-lo junto com este Dockerfile antes de iniciar o processo de compilação.
Nota: O procedimento explicado acima de copiar em uma configuração do Nginx permite grande flexibilidade e economiza muito tempo ao não lidar com a anexação e desanexação de contêineres para criar arquivos de configuração. Agora você pode simplesmente usar um para criar e executar uma imagem diretamente.
Crie um exemplo de nginx.conf
usando o editor de texto nano:
sudo nano nginx.conf
E substitua seu conteúdo para usá-lo como um proxy de encaminhamento para teste:
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
server {
listen 80;
location / {
proxy_pass http://httpstat.us/;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
Vamos salvar e sair do nginx.conf da mesma forma pressionando CTRL+X e confirmando com Y.
Essa imagem do docker nos permitirá portar todo o nosso progresso e criar rapidamente contêineres executando o Nginx com um único comando.
Para começar a usá-lo, crie uma nova imagem de contêiner com o seguinte:
sudo docker build -t nginx_img_1 .
E usando essa imagem - que marcamos como nginx_img_1 - podemos executar um novo contêiner:
sudo docker run -name nginx_cont_1 -p 80:80 -i -t nginx_img_1
Agora você pode visitar o endereço IP do seu droplet, e seu contêiner docker em execução Nginx fará seu trabalho, encaminhando você para a página de teste de status HTTP.
Exemplo:
# Usage: Visit http://[my droplet's ip]
http://95.85.10.236/200
Exemplo de resposta:
200 OK
Para obter o conjunto completo de instruções para instalar o docker (incluindo outros sistemas operacionais), confira a documentação de instalação do docker em docker.io.