Ideia central

Uma imagem Docker é um template read-only e imutável composto por camadas (layers). Cada instrução no Dockerfile adiciona uma nova camada. Containers são criados a partir de imagens: a imagem é o molde, o container é a instância.

Layers e cache

Imagens são construídas em camadas empilhadas usando Union File System. Cada layer representa uma mudança incremental:

┌─────────────────────┐  ← Layer: COPY app/ .
├─────────────────────┤  ← Layer: RUN npm install
├─────────────────────┤  ← Layer: WORKDIR /app
├─────────────────────┤  ← Layer: FROM node:20
└─────────────────────┘  ← Base image

O Docker cacheia layers: se uma layer não mudou, ela é reutilizada no próximo build. Por isso, coloque instruções que mudam com frequência (como COPY . .) depois das que mudam pouco (como RUN apt-get install).

Dockerfile

# Base image (sempre especifique a versão, evite :latest em produção)
FROM node:20-alpine
 
# Metadados opcionais
LABEL maintainer="[email protected]"
 
# Diretório de trabalho dentro do container
WORKDIR /app
 
# Copiar dependências primeiro (melhor uso de cache)
COPY package*.json ./
RUN npm ci --only=production
 
# Copiar o resto da aplicação
COPY . .
 
# Porta que a aplicação escuta (apenas documentação, não publica a porta)
EXPOSE 3000
 
# Comando padrão ao iniciar o container
CMD ["node", "server.js"]

Comandos essenciais

# Construir imagem a partir do Dockerfile no diretório atual
docker build -t minha-app:1.0 .
 
# Listar imagens locais
docker images
 
# Baixar imagem do registry
docker pull nginx:alpine
 
# Enviar imagem para um registry
docker push meu-usuario/minha-app:1.0
 
# Remover imagem
docker rmi minha-app:1.0
 
# Inspecionar camadas de uma imagem
docker history minha-app:1.0
 
# Remover imagens não utilizadas (dangling)
docker image prune

Multi-stage build

Técnica para reduzir o tamanho final da imagem, separando o ambiente de build do ambiente de runtime:

# Stage 1: build
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o servidor .
 
# Stage 2: runtime (imagem final muito menor)
FROM alpine:3.19
COPY --from=builder /app/servidor /servidor
CMD ["/servidor"]

.dockerignore

Equivalente ao .gitignore: evita copiar arquivos desnecessários para a imagem:

node_modules
.git
*.log
.env
dist

Conexões

Referências