Claude Code e Docker: Compose, volumes, redes e builds em CI
Use Claude Code para criar Dockerfile, Compose e builds de imagem em CI com segurança.
Defina o que o Claude Code deve fazer
Se você pedir apenas “coloque Docker neste app”, o Claude Code pode gerar um Dockerfile que sobe uma vez, mas não é fácil de revisar. Docker empacota o ambiente de execução: a imagem é o modelo, o contêiner é a instância em execução, o volume mantém dados fora do contêiner e a rede permite que serviços conversem pelo nome.
Em projeto real, o Dockerfile não é tudo. Revise Dockerfile, docker-compose.yml, .dockerignore, variáveis de ambiente, health checks e build em CI como um conjunto. Use as fontes oficiais: Dockerfile reference, Compose file reference, Docker build best practices, Docker Build GitHub Actions e Claude Code overview.
Para fechar o fluxo, combine com Claude Code CI/CD setup, approval and sandbox guide e security best practices.
Casos de uso práticos
A integração com Docker vale quando remove incerteza do trabalho diário. Escreva o problema antes de pedir mudanças.
| Caso de uso | O que Docker padroniza | O que pedir ao Claude Code |
|---|---|---|
| Onboarding de devs | Node.js, PostgreSQL, Redis, portas e comandos | Fazer docker compose up subir a stack |
| Debug próximo da produção | Variáveis, nomes de serviço, health checks, ordem de início | Listar diferenças entre local e produção |
| Verificação de PR | Dockerfile, lockfile, cache, logs de CI | Adicionar workflow que só faz build da imagem |
| Treinamento e handoff | Comandos, falhas, recuperação | Escrever regras em CLAUDE.md e README |
Em SaaS ou site monetizado, isso afeta receita. Checkout, formulários, painel admin e páginas de produto não podem depender de uma máquina específica. Pessoas trabalhando sozinhas podem começar por ClaudeCodeLab products. Times que precisam adaptar permissões, CI e revisão ao repositório real podem usar Claude Code training and consultation.
Prompt com limites claros
O primeiro prompt deve incluir contexto, arquivos esperados, restrições e verificação. Assim você evita uma configuração bonita, mas insegura.
Dockerize this Node.js + TypeScript API.
Context:
- pnpm is the package manager.
- The app listens on port 3000.
- GET /health returns 200.
- Local development needs PostgreSQL 16 and Redis 7.
Create:
- Production multi-stage Dockerfile
- docker-compose.yml for local development
- .dockerignore
- Docker-related package.json scripts
- GitHub Actions workflow that only verifies docker build
Constraints:
- Do not run the production container as root.
- Do not COPY .env files or secrets into the image.
- Explain the volume and network choices for the README.
- Include verification commands and how to inspect failures.
Um multi-stage build separa ambiente de build e runtime. Ferramentas de TypeScript ficam no stage de build; a imagem final recebe apenas dependências de produção e dist.
Dockerfile para copiar
O exemplo assume uma API Node.js que compila src/index.ts para dist/index.js. O stage dev é para Compose local e runner é para produção.
# syntax=docker/dockerfile:1
FROM node:22-bookworm-slim AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
WORKDIR /app
RUN corepack enable
FROM base AS dev
ENV NODE_ENV=development
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
CMD ["pnpm", "dev"]
FROM base AS deps
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
FROM deps AS build
COPY tsconfig.json ./
COPY src ./src
RUN pnpm build
FROM base AS prod-deps
ENV NODE_ENV=production
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod && pnpm store prune
FROM base AS runner
ENV NODE_ENV=production
RUN groupadd --system --gid 1001 nodejs \
&& useradd --system --uid 1001 --gid nodejs appuser
COPY --from=prod-deps --chown=appuser:nodejs /app/node_modules ./node_modules
COPY --from=build --chown=appuser:nodejs /app/dist ./dist
COPY --chown=appuser:nodejs package.json ./
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --retries=3 CMD node -e "fetch('http://127.0.0.1:3000/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
CMD ["node", "dist/index.js"]
Peça ao Claude Code para revisar se secrets entram na imagem, se a ordem de COPY preserva cache e se devDependencies ficaram fora do runtime.
Compose: volumes e redes
Compose sobe vários contêineres juntos. API, PostgreSQL e Redis compartilham a rede; a API acessa postgres e redis pelo nome do serviço. Volumes mantêm dados fora de contêineres descartáveis. pgdata preserva o banco e api_node_modules impede que node_modules do host sobrescreva dependências Linux.
services:
api:
build:
context: .
target: dev
command: pnpm dev
ports:
- "3000:3000"
environment:
NODE_ENV: development
DATABASE_URL: postgres://app:app@postgres:5432/app
REDIS_URL: redis://redis:6379
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
volumes:
- .:/app
- api_node_modules:/app/node_modules
healthcheck:
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
interval: 10s
timeout: 3s
retries: 5
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: app
POSTGRES_DB: app
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d app"]
interval: 5s
timeout: 3s
retries: 10
redis:
image: redis:7-alpine
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
volumes:
pgdata:
api_node_modules:
depends_on controla ordem de início, mas não prova que o banco aceita conexões. Use healthcheck e condition: service_healthy.
Mantenha secrets fora do build
Comece por .dockerignore. Ele reduz o contexto e evita copiar .env.
.git
node_modules
dist
coverage
.env
.env.*
!.env.example
npm-debug.log*
pnpm-debug.log*
Dockerfile*
docker-compose*.yml
Depois adicione scripts compartilhados no package.json.
{
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc -p tsconfig.json",
"start": "node dist/index.js",
"docker:dev": "docker compose up --build",
"docker:check": "bash scripts/docker-check.sh"
},
"dependencies": {
"@fastify/redis": "latest",
"fastify": "latest",
"pg": "latest"
},
"devDependencies": {
"tsx": "latest",
"typescript": "latest"
}
}
Script de verificação repetível
Comandos manuais são esquecidos. Guarde o fluxo em scripts/docker-check.sh.
#!/usr/bin/env bash
set -euo pipefail
docker compose build api
docker compose up -d postgres redis api
cleanup() {
docker compose down
}
trap cleanup EXIT
for attempt in {1..30}; do
if curl -fsS http://127.0.0.1:3000/health >/dev/null; then
echo "healthcheck ok"
exit 0
fi
echo "waiting for api... ${attempt}/30"
sleep 2
done
docker compose logs api
exit 1
O script faz build, sobe a stack, espera /health e imprime logs se a API nunca ficar saudável.
CI: build primeiro, push depois
No primeiro PR, verifique apenas se a imagem faz build. Push, assinatura, scan e SBOM podem vir depois.
name: docker-build
on:
pull_request:
push:
branches:
- main
jobs:
image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v7
with:
context: .
target: runner
push: false
tags: claude-code-docker-sample:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
O Claude Code deve explicar se o workflow publica algo, se as permissões são excessivas e como ele se comporta sem cache.
Falhas comuns
A falha mais cara é copiar .env para a imagem. Se um secret entra no registry, a limpeza demora. Revise .dockerignore, secrets de CI e logs de build juntos.
Outra falha é montar node_modules do host dentro de um contêiner Linux. Pacotes nativos podem diferir entre macOS, Windows e Linux. Um volume nomeado separa isso.
Também há corrida de inicialização: a API sobe antes do PostgreSQL estar pronto. Combine health checks e retry na aplicação.
Por fim, não rode produção como root. Funciona em demo, mas aumenta o impacto de uma falha. Peça ao Claude Code que aponte as linhas que comprovam usuário non-root.
Fluxo seguro
A ordem recomendada é: inspecionar o repositório, listar dependências de runtime, escrever .dockerignore, criar Compose local, criar Dockerfile de produção, adicionar script de verificação e só então CI. Depois de cada etapa, leia git diff e peça ao Claude Code: arquivos alterados, motivo, comando de verificação e risco restante.
Isso combina com session handoff template. Docker deve virar hábito revisável do time, não um arquivo gerado uma vez.
Resultado prático
Na prática, dividir a tarefa melhorou a qualidade do Claude Code. .dockerignore, depois Compose, depois health checks e depois CI geraram diffs mais fáceis de revisar. O volume api_node_modules e a espera por service_healthy reduziram dois problemas de iniciante: “só funciona na minha máquina” e “a API subiu, mas não conecta ao Postgres”.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Workflow Obsidian para CLAUDE.md com Claude Code
Transforme notas de trabalho do Obsidian em notas operacionais CLAUDE.md para preservar contexto.
Claude Code Revenue CTA Routing: artigos para PDF, Gumroad e consultoria
Um fluxo com Claude Code para levar leitores ao PDF grátis, Gumroad ou consultoria conforme intenção.
Regras de handoff para equipes com Claude Code: evidências, permissões, rollback e receita
Formato prático para entregar trabalho do Claude Code com prova, permissões, rollback, PDF grátis, Gumroad e consultoria.