DEV Community

Felipe Oliveira for Felipe Oliveira (pt-BR)

Posted on • Edited on

Docker: Parte 2 - Criação de Imagens e Execução de Containers

Olá, venho anotando os meus estudos no Notion e aos poucos postando aqui também, meu objetivo puro e simples é transmitir conhecimento e ter algum local de referência para buscas.

Seguindo nessa segunda parte de estudos sobre o Docker vamos a algumas observações:

  • Se não existe nenhum processo rodando dentro do container o mesmo é finalizado.

  • Ao executarmos os containers através do docker, sem usar extensões como o Docker-compose que veremos mais a frente, temos que passar manualmente os parâmetros sobre o container com informações como nome, portas, variáveis de ambiente, etc.

Dockerfile

Esse arquivo reune as informações necessárias para a execução da nossa aplicação, como o Node do Javascript ou Maven para aplicações Java.

Nele configuramos em scripts os mesmos passos que executamos para rodar a aplicação, indicamos o diretório a ser trabalho, rodamos ‘npm install’, copiamos os arquivos do build e inicializamos o servidor.

Exemplo simplificado:

# Imagem base. Essa versão 'alpine' é uma versão de tamanho reduzido.
# Ao subirmos uma imagem na nuvem somos cobrados pelo tamanho da mesma então
# quanto menor, melhor, nesse caso temos uma redução de mais de 1GB para cerca de 
# 500mb nas imagens alpine.
FROM node:20-alpine

# Cria o diretório
WORKDIR /app

# Adiciona variáveis de ambiente
ENV DB_USER=postgres

# Um asterisco é usado para garantir que tanto o package.json quanto o 
# package-lock.json serão copiados
COPY package*.json ./

# Instala as dependências da aplicação
RUN npm install

# Copia o código-fonte da aplicação
COPY . .

# Cria uma pasta "dist" com o build de produção
RUN npm run build

# Expõe a porta 3000
EXPOSE 3000

# Inicia o servidor usando o build de produção
CMD [ "node", "dist/main.js" ]
Enter fullscreen mode Exit fullscreen mode

Também possuimos um arquivo ignore para que o Docker não inclua eles no build da imagem.

*Como a imagem executará os mesmos passos que executamos para iniciar o projeto, não precisaremos incluir a pasta node_modules, pois a mesma será gerada

Dockerfile
.dockerignore
node_modules
npm-debug.log
dist
Enter fullscreen mode Exit fullscreen mode

Gerando uma imagem a partir do Dockerfile

Com o Dockerfile configurado, conseguimos gerar a imagem com o seguinte comando:

# Aonde "-t" é a tag1.0 é a versão e o ponto especifica a raiz aonde o nosso 
# arquivo Dockerfile está localizado, sendo nesse caso na raiz de onde estamos 
# executando o comando.
# O "." indica que o Dockerfile está na raiz do meu diretório aonde estou
# executando o comando.
docker build -t nome-da-imagem:1.0 .

docker build -t [nome-da-imagem]:[tag] [caminho]
Enter fullscreen mode Exit fullscreen mode

Executando um Container

O container possui uma interface de rede separada do host, para conseguir acessá-lo precisamos passar um comando ao executa-lo fazendo o mapeamento das portas do container para as portas do host.

Aonde do lado direito temos a porta do container e do lado esquerdo a porta do host.

*Se possuirmos alguma variável de ambiente a mesma também deverá ser informada no comando.

## Executar um container

# Mapeando a porta definida no EXPOSE do Dockerfile para uma porta aleatoria 
# no host
docker run -p my-image:1.0

# Mapeando a porta 8080 do container para a porta 3000 no meu host
docker run -p 3000:8080 my-image:1.0

# Com variáveis de ambiente
docker run -d -p 3000:3000 -e NODE_ENV=development -e DB_HOST=db.example.com -e DB_PORT=5432 -e DB_USER=myuser -e DB_PASS=mypassword --name my-node-app my-node-app-image

docker run -d \
  -p 3000:3000 \
  -e NODE_ENV=development \
  -e DB_HOST=db.example.com \
  -e DB_PORT=5432 \
  -e DB_USER=myuser \
  -e DB_PASS=mypassword \
  --name my-node-app \
  my-node-app-image
Enter fullscreen mode Exit fullscreen mode

Melhores Práticas do Dockerfile:

Por fim, deixo aqui um resumo de algumas práticas indicadas na documentação.

  • Use Multi-Stage builds Quando temos multiplos FROM separando os diferentes estágios do build que podem ser carregados do anterior para o próximo, a fim de organizar o arquivo e deixar definido as responsabilidades.
  • Selecione a imagem base correta Escolha uma imagem pequena e local confiável (Docker Hub, Verified Publisher, Docker Sponsored Open Source)
  • Reconstrua (rebuild) suas imagens com frequência As imagens são imutáveis. Ao fazer um build, tiramos um “snapshot” daquele momento, portanto, qualquer alteração subsequente necessita de um novo build na imagem.
  • Podemos usar um arquivo .dockerignore Podemos inserir arquivos não relevantes para o build aqui.
  • Desaccople as aplicações Cada container deve ter apenas uma responsabilidade
  • Organize argumentos multi-linhas É possível separar os argumentos em múltiplas linhas

Exemplo de organização dos argumentos em múltiplas linhas:

RUN npm install -g \
  typescript \
  eslint \
  nodemon \
  jest \
  pm2 \
  && npm cache clean --force
Enter fullscreen mode Exit fullscreen mode

Fontes:

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay