How to criar Dockerfiles eficientes com multi stage builds
Multi stage builds são uma das melhores features do Docker para manter imagens pequenas e organizadas. Vou mostrar como aplicar isso em um projeto Python real.
Crie um arquivo app.py simples:
# app.py
def main():
print("Hello from a multi stage build")
if __name__ == "__main__":
main()
Dockerfile sem multi stage
Agora crie o Dockerfile sem multi stage:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
Essa imagem inclui o pip, o cache do pip e ferramentas de build que não precisamos em produção. O resultado é uma imagem maior que o necessário.
Dockerfile com multi stage builds
Com multi stage builds separamos o ambiente de build do ambiente final. Veja o mesmo Dockerfile com dois stages:
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY . .
CMD ["python", "app.py"]
O primeiro stage instala as dependências. O segundo stage copia só o que importa. O resultado é uma imagem final muito menor.
Para construir e ver o tamanho:
docker build -t minha-app .
docker images | grep minha-app
Exemplo com Go (linguagem compilada)
Para linguagens compiladas como Go o ganho é ainda maior. Veja um exemplo com uma aplicação Go:
FROM golang:1.23 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server
FROM scratch
COPY --from=builder /app/server /server
CMD ["/server"]
A imagem final começa do zero (scratch). Não tem shell, sistema operacional, nem ferramentas de build. Só o binário compilado.
Dica prática
Sempre nomeie seus stages com AS para facilitar a leitura. Use nomes como builder, test, ou dev. Isso ajuda a saber o que cada stage faz sem precisar contar linhas.
That's all for now. Thanks for reading!
Comments
No comments yet. Start the discussion.