🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

Como otimizar imagens Docker: reduzir o tamanho em 90% em 2026

⏱️5 min read  ·  1,045 words

Imagens inchadas do Docker retardam implantações, desperdiçam armazenamento, aumentam a superfície de ataque e custam dinheiro em largura de banda. Uma imagem Node.js ou Python não otimizada típica pode ter mais de 1 GB; com as técnicas certas, o mesmo aplicativo cabe em menos de 100 MB. Veja como reduzir drasticamente as imagens do Docker.

Por que o tamanho da imagem é importante

  • Implantações mais rápidas: Imagens menores são puxadas e iniciadas mais rapidamente, especialmente durante o dimensionamento
  • Custos mais baixos: Menos armazenamento de registro e largura de banda (é importante em escala)
  • Superfície de ataque menor: Menos pacotes significa menos vulnerabilidades
  • CI/CD mais rápido: Criar e enviar imagens menores acelera pipelines

Técnica 1: Construções em vários estágios (maior vitória)

Construa em um estágio com todas as ferramentas de construção e copie apenas o artefato final em uma imagem limpa e mínima:

# 🐛 Single-stage — includes build tools, dev deps, source (1.1GB)
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]

# ✅ Multi-stage — final image has only runtime + built output (150MB)
# Build stage
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Runtime stage — clean slate
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev            # production deps only
COPY --from=builder /app/dist ./dist   # copy ONLY the built output
CMD ["node", "dist/index.js"]

Técnica 2: Use imagens de base mínimas

Imagem base Tamanho aproximado Notas
nó:20 ~1,1 GB Debian completo — evite para produção
nó:20-slim ~240 MB Debian cortado — bom padrão
nó:20-alpino ~180 MB Alpine Linux — pequeno, comum
gcr.io/distroless/nodejs ~170 MB Sem gerenciador de shell/pacote — mais seguro
# Alpine — smallest common choice
FROM node:20-alpine

# Distroless — no shell, no package manager, minimal attack surface
FROM gcr.io/distroless/nodejs20-debian12
COPY --from=builder /app/dist /app/dist
CMD ["/app/dist/index.js"]

Técnica 3: Otimize o cache de camadas

# 🐛 Copying everything first breaks caching — any code change
#    re-runs npm install
COPY . .
RUN npm ci

# ✅ Copy dependency files first, install, THEN copy source
COPY package*.json ./
RUN npm ci                # this layer is cached unless package.json changes
COPY . .                  # only this layer rebuilds on code changes
RUN npm run build

Ordene as instruções do Dockerfile das menos alteradas para as mais alteradas. As dependências mudam raramente, a fonte muda constantemente – portanto, instale as dependências antes de copiar a fonte para maximizar os acessos ao cache.

Técnica 4: Use .dockerignore

# .dockerignore — exclude files that bloat the build context
node_modules
npm-debug.log
.git
.gitignore
.env
.env.*
dist
coverage
.vscode
.idea
README.md
*.md
.DS_Store
tests
**/*.test.js

Sem.dockerignore, COPY . . envia todo o seu diretório (incluindo node_modules, .git) para a compilação – retardando as compilações e potencialmente vazando segredos.

Técnica 5: Combine e limpe comandos RUN

# 🐛 Each RUN creates a layer; cleanup in a separate layer doesn't shrink
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*   # too late — previous layers keep the data

# ✅ Combine into one layer with cleanup in the same RUN
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/*   # cleanup in the SAME layer

Exemplo de Python: Multiestágio + Slim

# Build stage — compile dependencies
FROM python:3.12 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# Runtime stage — slim base + only installed packages
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]
# Result: ~150MB instead of ~1GB

Medindo e analisando o tamanho da imagem

# Check image size
docker images myapp

# Analyze layers to find what's taking space
docker history myapp:latest

# Use 'dive' for detailed layer analysis
dive myapp:latest
# Shows wasted space and what each layer adds

Lista de verificação de otimização

  • Use compilações de vários estágios — copie apenas artefatos de tempo de execução para a imagem final
  • Use imagens de base alpinas, finas ou distroless
  • Copie os arquivos de dependência e instale antes de copiar a origem (cache da camada)
  • Adicione um abrangente.dockerignore
  • Instale apenas dependências de produção (npm ci --omit=dev, pip --no-cache-dir)
  • Combine comandos RUN e limpe na mesma camada
  • Fixe versões de imagem base para reprodutibilidade

Perguntas frequentes

Q: Alpine é sempre a melhor imagem base?
R: Geralmente menor, mas Alpine usa musl libc que ocasionalmente causa problemas com módulos nativos ou DNS. Se você tiver problemas de compatibilidade, use slim (baseado em Debian) – ainda é pequeno e mais compatível. Distroless é melhor for security.

Q: What is distroless and should I use it?
A: Distroless images contain only your app and its runtime — no shell, no package manager, minimal OS. This shrinks size and dramatically reduces attack surface. Great for production, but harder to debug (no shell to exec into).

Q: How much smaller can I realistically get?
A: Multi-stage builds plus a minimal base commonly reduce images by 70-90%. Uma imagem Node.js de 1 GB geralmente fica entre 100 e 150 MB. O Distroless pode ficar ainda menor

P: O tamanho da imagem afeta o desempenho do tempo de execução?
P: Por que minha imagem permanece grande apesar dos comandos de limpeza?

R: As camadas do Docker são imutáveis — se você adicionar arquivos em uma camada e excluí-los em outra, os dados excluídos ainda existirão na camada anterior. A otimização das imagens do Docker se resume a algumas técnicas de alto impacto:
compilações de vários estágios

imagens

(alpine, slim ou distroless),cache de camada inteligente(dependências antes da fonte) e um.dockerignoreAplique a lista de verificação aos seus arquivos Docker e meça os resultados.Aplique a lista de verificação aos seus arquivos Docker e meça os resultados.Aplique a lista de verificação aos seus arquivos Docker e meça os resultados.Aplique a lista de verificação aos seus arquivos Docker e meça os resultados.Aplique a lista de verificação aos seus arquivos Docker e meça os resultados.docker history or dive.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা