Dicas para reduzir o tamanho de imagens Docker
Imagens Docker grandes são um problema comum em ambientes de produção. Elas consomem mais espaço em disco, aumentam o tempo de deploy e tornam o pull de imagens mais lento em clusters Kubernetes. Felizmente, existem técnicas comprovadas para reduzir significativamente o tamanho das suas imagens sem comprometer a funcionalidade.
1. Escolha a imagem base correta
A escolha da imagem base é o fator que mais impacta o tamanho final. Uma imagem Ubuntu completa pode ter mais de 200 MB, enquanto alternativas mais enxutas oferecem reduções drásticas.
# Ruim: imagem completa do Ubuntu
FROM ubuntu:22.04
# Tamanho: ~200 MB
# Bom: versão slim do Python
FROM python:3.11-slim
# Tamanho: ~120 MB
# Melhor: Alpine Linux
FROM python:3.11-alpine
# Tamanho: ~45 MB
# Excelente: Distroless (apenas runtime)
FROM gcr.io/distroless/python3
# Tamanho: ~30 MB
Sempre evite usar a tag latest. Prefira tags específicas como python:3.11-slim-bookworm para garantir reprodutibilidade e evitar surpresas com atualizações.
2. Otimização de camadas com Dockerfile multi-stage
O multi-stage build é uma das técnicas mais poderosas para reduzir tamanho. Você cria um ambiente de build com todas as ferramentas necessárias e depois copia apenas os artefatos finais para uma imagem mínima.
# Estágio 1: Build
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server
# Estágio 2: Runtime
FROM alpine:3.19
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/server /server
EXPOSE 8080
CMD ["/server"]
A imagem final conterá apenas o binário compilado e as bibliotecas essenciais, reduzindo de ~800 MB (Go completo) para ~15 MB.
3. Minimize o número de camadas e comandos RUN
Cada instrução RUN, COPY ou ADD cria uma nova camada. Combine comandos relacionados em um único RUN para reduzir o número de camadas e o tamanho final.
# Ruim: múltiplos RUNs criam várias camadas
RUN apt-get update
RUN apt-get install -y curl git
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*
# Bom: comandos combinados em um único RUN
RUN apt-get update && \
apt-get install -y --no-install-recommends curl git && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
A segunda abordagem não apenas reduz camadas, mas também garante que arquivos temporários sejam removidos na mesma camada em que foram criados, evitando que ocupem espaço desnecessário.
4. Gerencie dependências de forma inteligente
Instale apenas o necessário para produção e remova arquivos que não são úteis em runtime.
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
# Instalar apenas dependências de produção
RUN npm ci --only=production && \
npm cache clean --force
COPY . .
# Remover arquivos de desenvolvimento
RUN rm -rf tests/ docs/ *.md .gitignore
Para Python, use o pip com flags apropriadas:
FROM python:3.11-alpine
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt && \
find /usr/local -type f -name "*.pyc" -delete && \
find /usr/local -type d -name "__pycache__" -delete
5. Utilize .dockerignore e compressão de camadas
O arquivo .dockerignore evita que arquivos desnecessários sejam enviados para o daemon Docker, reduzindo o contexto de build e o tamanho das camadas.
# .dockerignore
node_modules
.git
.env
*.md
tests/
docs/
Dockerfile
.gitignore
.vscode/
__pycache__/
*.pyc
dist/
*.log
Lembre-se que o Docker reutiliza camadas em cache. Se você copiar node_modules inteiro e depois removê-lo em um comando RUN, o espaço ainda será ocupado na camada anterior. Sempre evite copiar diretórios que serão removidos posteriormente.
6. Compactação e pós-processamento da imagem final
Ferramentas especializadas podem analisar e reduzir ainda mais o tamanho das imagens.
# Usando docker-slim para otimizar imagem existente
docker-slim build --target myapp:latest --tag myapp:slim
# Analisando camadas com dive
dive myapp:latest
O dive mostra o tamanho de cada camada e identifica arquivos desnecessários. O docker-slim pode reduzir imagens em até 90% removendo bibliotecas não utilizadas.
Para binários totalmente estáticos (Go, Rust), considere usar scratch como base:
FROM scratch
COPY --from=builder /app/server /server
EXPOSE 8080
CMD ["/server"]
7. Monitoramento contínuo e boas práticas de CI/CD
Integre verificações de tamanho no seu pipeline para evitar que imagens cresçam com o tempo.
# Exemplo de workflow GitHub Actions
name: Docker Image Check
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build and analyze
run: |
docker build -t myapp:latest .
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
wagoodman/dive:latest myapp:latest
- name: Check image size
run: |
SIZE=$(docker images myapp:latest --format "{{.Size}}" | \
sed 's/MB//' | sed 's/GB//')
if (( $(echo "$SIZE > 200" | bc -l) )); then
echo "Image too large: $SIZE MB"
exit 1
fi
Defina limites claros: imagens Python/Node abaixo de 200 MB, Go/Rust abaixo de 50 MB. Use ferramentas como Trivy ou Snyk para identificar dependências desnecessárias e vulnerabilidades.
Resumo das principais técnicas
| Técnica | Redução típica | Esforço |
|---|---|---|
| Imagem base Alpine | 70-80% | Baixo |
| Multi-stage build | 50-90% | Médio |
| Combinar RUNs | 10-30% | Baixo |
| .dockerignore | 20-50% | Baixo |
| docker-slim | 50-90% | Alto |
Comece pelas técnicas de menor esforço (imagem base, .dockerignore) e avance para multi-stage e docker-slim conforme necessário. Cada megabyte economizado em uma imagem Docker se multiplica pelo número de deploys e ambientes, resultando em economia significativa de tempo e recursos.
Referências
- Docker Best Practices: Choosing a Base Image — Documentação oficial do Docker sobre escolha de imagens base e boas práticas de Dockerfile
- Multi-stage Builds in Docker — Guia completo sobre builds multi-estágio com exemplos práticos
- Alpine Linux Docker Images — Página oficial do Alpine Linux com informações sobre tamanhos e pacotes disponíveis
- Dive: Docker Image Analysis Tool — Ferramenta open source para inspecionar camadas de imagens Docker e identificar oportunidades de redução
- docker-slim: Minimize Container Images — Ferramenta avançada para reduzir automaticamente o tamanho de imagens Docker em até 90%
- Distroless Docker Images by Google — Repositório oficial das imagens Distroless, com documentação sobre como usá-las em produção
- Trivy: Vulnerability Scanner for Containers — Scanner de vulnerabilidades que também ajuda a identificar dependências desnecessárias em imagens Docker