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”.
Artigos relacionados
Kubernetes com Claude Code: Deployment, Service, Ingress e rollback
Guia prático para criar manifests Kubernetes seguros com Claude Code, probes, recursos, CI e rollback.
Claude Code × AWS ECS/Fargate Guia Completo | Automatize Deployments Seguros
Implante ECS/Fargate com Claude Code: Docker, ECR, task definitions, logs, IAM e armadilhas reais.
Claude Code e Devcontainer: ambiente de desenvolvimento reproduzível
Monte um devcontainer Claude Code com Dockerfile, permissões, segredos, volumes e portas.
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.