Docker Visão Geral (Parte 2)
Como criar suas próprias imagens docker na prática.
Na primeira parte deste artigo falei sobre o que o Docker, mostrei alguns comandos e como a executar aplicações que já foram conteinerizadas. Esse artigo pode ser acessado aqui.
Criando imagens próprias
A ideia aqui vai ser mostrar 2 exemplos de imagens personalizadas para dar uma luz de como funciona a brincadeira. Antes de começar, preciso explicar que, as imagens Docker são geradas a partir de arquivo chamado Dockerfile. Esse será nosso principal objeto de estudo aqui.
Aplicação estática Nginx
Nosso primeiro exemplo será uma aplicação estática, basicamente HTML puro. Para montar essa imagem usaremos o Nginx como base, que é um servidor web muito poderoso que merece um artigo só para falar sobre ele.
Para criar essa imagem vamos precisar usar uma pré-existente como base, como já mencionei nesse caso será a do Nginx. Essa imagem base pode ser encontrada no Docker Hub, lá já será possível encontrar explicações do que é o Nginx e de como utilizar a imagem. Uma das partes mais importantes desta página é a sessão de “tags”, onde podem ser encontradas quais “tags” estão disponíveis. Essas “tags” basicamente são a referência de onde veio essa imagem, sobre qual SO e/ou imagem Docker ela foi construída.
- Pasta de trabalho:
Vamos começar mostrando como vai ficar nossa pasta de trabalho, teremos basicamente 2 arquivos, index.html
e o Dockerfile
. Então nossa pasta fica assim:
- O HTML
O arquivo index.html
vai ser bem simples, só para mostrar alguma coisa diferente da página padrão do Nginx. Esse arquivo fica assim (conteúdo auto gerado pelo VS Code + o hello world):
- Dockerfile
Em nosso Dockerfile
vamos usar o comando:
FROM nginx:alpine
Esse comando diz ao Docker qual a imagem base nginx
, e qual a “tag” dessa imagem alpine
. Logo depois usaremos o comando:
COPY index.html /usr/share/nginx/html/
Onde o COPY
é o comando que diz de onde vem o arquivo index.html
e para onde ele vai (nesse caso dentro do contêiner) /usr/share/nginx/html/
. Nosso arquivo fica assim:
Com o Dockerfile pronto basta executar o build da imagem, no terminal, usando o comando:
docker build -t mynginx .
Que vai executar o build e nomear a imagem, a saída no console será algo como:
Para testar a imagem é só executar um contêiner a partir dela, o comando:
docker run -p 80:80 mynginx
Vai fazer isso, o detalhe aqui é a flag -p
que vinculará a porta 80
do contêiner com à80
do “host”. Acessando localhost
no navegador podemos ver o resultado:
Aplicação Nodejs
Para criar uma imagem baseada em Nodejs não é muito diferente da que já criamos, as diferenças que vamos encontrar aqui serão por conta das peculiaridades do Nodejs. Nesse exemplo vamos criar uma aplicação que usa Node+Express para mandar um hello world
como no caso anterior.
- Pasta de trabalho:
Começaremos vendo como fica nossa pasta de trabalho:
- Tratando dependências do Nodejs
Nesse exemplo além do node, precisaremos utilizar uma dependência, o Express. Para que isso funcione vamos criar um package.json
, e adicionar o Express como dependência, para isso executaremos o comando:
npm init -y
O resultado é algo do tipo:
Agora que temos o package.json vamos instalar o Express como dependência e salva-lo no package.json. O npm nos permite fazer isso executando apenas uma linha de código, para isso executaremos o comando:
npm i -s express
O resultado dessa execução vai ser algo assim:
Depois disso nosso package.json fica assim:
- O conteúdo do server.js
Depois de passarmos pelo tratamento de dependências do Node, vamos ver como fica o server.js:
- Dockerfile
Agora que já atendemos a todos os pré requisitos para fazer o Node funcionar com Express, nosso Dockerfile fica assim:
Onde:
- No
FROM
temos a referência de qual imagem vamos utilizar como base; - No
WORKDIR
escolhemos uma pasta onde colocaremos os arquivos do projeto, caso não exista será criada; COPY . .
irá copiar todo conteúdo que está na raiz do projeto e jogar para dentro da pasta de trabalho da imagem;- Já o
RUN
executa comandos de terminal durante a construção da imagem; - Por fim o
CDM
também executará um comando de terminal, com a diferença que esse só vai acontecer quando um contêiner, que use essa imagem como base, for ligado.
Agora para fazer a mágica acontecer vamos seguir os mesmos passos do exemplo anterior, docker build
para criar a imagem e docker run
para executar um contêiner a partir dessa imagem.
Pronto, agora quando acessamos pelo navegador, conseguimos ver nosso hello world
:
Conclusão
Como podemos ver nos 2 exemplos a cima, ao criar uma imagem Docker o padrão de criação do Dockerfile e até a execução dos comandos Docker vão ser sempre muito similares. As diferenças entre imagens vão depender mais da aplicação do que do Docker.
Claro que para esse exemplo eu quis simplificar, e até ignorei algumas boas práticas, para encurtar o texto. De qualquer forma o objetivo aqui não era falar sobre boas práticas e sim mostrar como o Docker pode facilitar nossa vida, visto que a partir de um arquivo simples conseguimos executar aplicações, que foram desenvolvidas em linguagens diferentes, sem instalar mais nada além do próprio Docker.