Docker: Algumas boas práticas para a criação de Dockerfiles

Dockerfiles são a base para a construção de imagens Docker, peça fundamental no desenvolvimento e implantação de aplicações containerizadas. Para criar Dockerfiles robustos, eficientes e fáceis de manter, é essencial seguir boas práticas. Neste guia, você vai aprender as principais boas práticas para Dockerfiles com exemplos práticos e comandos reais.

1- Minimize o número de camadas consolidando as instruções


❌ Evite: múltiplas camadas desnecessárias

RUN apk update
RUN apk add curl
RUN apk add vim

✅ Faça: consolide em uma única camada

RUN apk update && \
apk add curl && \
apk add vim

Cada instrução em um Dockerfile cria uma nova camada na imagem Docker. Quanto mais instruções, mais camadas – e isso impacta diretamente o desempenho, o tempo de build e o tamanho final da imagem. Por isso, o número de instruções deve ser reduzido ao mínimo possível.

2- Evite instalar pacotes desnecessários

Uma das principais boas práticas para Dockerfiles é evitar pacotes desnecessários. Isso reduz a complexidade, as dependências, o tamanho da imagem e o tempo de build – resultando em containers mais seguros e eficientes.

❌ Evite: instalar pacotes que você não vai usar

RUN apk add vim git curl wget openssh postgresql-client

✅ Faça: instale apenas o necessário para sua aplicação

RUN apk add –no-cache curl

3- Utilize o arquivo .dockerignore

Uma das boas práticas para Dockerfiles mais subestimadas é o uso do arquivo .dockerignore. Assim como o .gitignore, ele exclui arquivos e pastas do contexto de build – o que aumenta o desempenho, reduz o tamanho do contexto e melhora a segurança.

Crie seu Dockerfile em uma pasta dedicada, adicione apenas os arquivos necessários e configure o .dockerignore para excluir o restante.

4- Processe o Dockerfile usando o cache

Uma das boas práticas para Dockerfiles mais importantes é entender e aproveitar o cache do Docker. Durante o build, o Docker reutiliza camadas em cache sempre que possível, acelerando drasticamente o processo. No entanto, quando necessário, você pode desabilitar o cache com --no-cache:

docker build --no-cache -t minha-aplicacao .

5- Utilize somente as imagens oficiais

6- Construa imagens usando Multi-stage

Uma das boas práticas para Dockerfiles mais impactantes é o Multi-stage Build. Essa técnica permite que você inclua na imagem final apenas os binários e dependências mínimas essenciais – excluindo compiladores, SDKs e ferramentas de desenvolvimento.

Os benefícios são claros:

  • 📦 Redução drástica do tamanho da imagem final
  • ⚡ Diminuição do tempo de build
  • 🔒 Redução da superfície de ataque e vulnerabilidades

É a técnica recomendada para imagens de produção.

Exemplo de um script em go

// Arquivo main.go
package main

import "fmt"

func main() {
fmt.Println("Hello, World!")
}
# Arquivo Dockerfile
FROM golang:1.21.0-alpine3.17

WORKDIR /app
ADD main.go /app/

RUN go build -o script-deltaops main.go

CMD ["./script-deltaops"]

No exemplo anterior, criamos um script simples em Go que gera um binário. Ao executar docker images, o tamanho da imagem construída foi de 250 MB – bastante pesado para uma aplicação que só imprime “Hello, World!”.

Por que a imagem ficou tão grande?

Porque usamos a imagem completa do Golang (golang:1.21.0-alpine3.17), que inclui o compilador, SDK e diversas ferramentas de desenvolvimento. Tudo isso é necessário para compilar o código, mas não para executá-lo.

A solução: Multi-stage Build

Agora vamos criar um Dockerfile usando a abordagem de multi-stage build e comparar os resultados. Você vai ver como podemos reduzir o tamanho da imagem final drasticamente – mantendo apenas o binário gerado e descartando todo o resto.

# Arquivo Dockerfile Multistage

# Construção da imagem para fazer o Build
FROM golang:1.21.0-alpine3.17 AS novo-build
WORKDIR /app
ADD main.go /app/
RUN go build -o script-deltaops main.go
# Copia do binario gerado pelo Build
FROM alpine:latest
WORKDIR /app
COPY --from=novo-build /app/script-deltaops /app/script-deltaops
CMD ["./app/script-deltaops"]

Comparando os resultados do exemplo, fica clara a importância do multi-stage build como uma das principais boas práticas para Dockerfiles.

Enquanto o single-stage gerou uma imagem de 250 MB (incluindo compilador Go e SDK), a versão com multi-stage produziu uma imagem final de apenas ~10 MB – uma redução de 96%!

Como funciona: a primeira etapa (builder) compila o código em uma imagem completa; a segunda etapa copia apenas o binário gerado para uma imagem mínima. Resultado: uma imagem Docker enxuta, segura e pronta para produção.

7- Utilize imagens otimizadas, como a imagem Alpine, por exemplo.

Usamos a tag :latest, pois essa é a tag de imagem padrão que o Docker busca no Docker Hub. Conforme mostrado acima com o exemplo do Python, se você buscar a versão alpine da imagem, o tamanho reduz em quase 95%!

Conclusão

Neste post, apresentei 7 boas práticas essenciais para a criação de Dockerfiles eficientes:

  1. ✅ Consolide instruções para minimizar camadas
  2. ✅ Evite pacotes desnecessários
  3. ✅ Utilize .dockerignore
  4. ✅ Aproveite o cache do Docker
  5. ✅ Prefira imagens oficiais
  6. ✅ Adote multi-stage build
  7. ✅ Use imagens Alpine

Com essas dicas, você conseguirá reduzir significativamente o tamanho das suas imagens, acelerar os builds e aumentar a segurança dos seus containers.

🚀 Próximos passos

Tem alguma dúvida sobre as boas práticas ou quer compartilhar sua própria dica? Deixe nos comentários abaixo!

📢 Siga a DeltaOps nas redes sociais para mais conteúdos sobre Docker, containers e DevOps:

LinkedIn