Como diminuir o tamanho do container usando multi-stage builds.

De vez em quando esbarro com alguma imagem docker enorme em que 99% do tamanho é lixo deixado quando a imagem estava sendo construída. Isso é especialmente ruim quando estamos de executáveis Go que são autocontidos e geralmente não precisam de nenhum recurso externo, nem mesmo a libc.

multi-stage builds

A solução é usar multi-stage builds, dessa forma você pode ter duas etapas no seu Dockerfile, uma de compilação que baixa o que for necessário, compila o código, etc. e outra que apenas copia os executáveis e os recursos para os locais esperados e nem precisa ser baseada em alguma distribuição, pode ser uma imagem scretch que reduz ainda mais o tamanho final.

Exemplo de Dockerfile

Este é um pequeno exemplo de Dockerfile que usa multi-stage builds para primeiro criar um executável e em seguida criar uma imagem que contém apenas o próprio executável e mais nada.

FROM golang:latest as build
WORKDIR /build
ADD . .
RUN CGO_ENABLED=0 GOOS=linux \
    go build -ldflags '-extldflags "-static"' -o app

FROM scratch
COPY --from=build /build/app /app
ENTRYPOINT ["/app"]

Pontos positivos

Pontos negativos

Boa prática

Usar multi-stage build é sem dúvida uma boa prática não importando a linguagem, é simples de implementar e os pontos negativos são facilmente contornados.

Cesar Gimenes