Use Cases (Atualizado: 03/06/2026)

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.

Claude Code e Docker: Compose, volumes, redes e builds em CI

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 usoO que Docker padronizaO que pedir ao Claude Code
Onboarding de devsNode.js, PostgreSQL, Redis, portas e comandosFazer docker compose up subir a stack
Debug próximo da produçãoVariáveis, nomes de serviço, health checks, ordem de inícioListar diferenças entre local e produção
Verificação de PRDockerfile, lockfile, cache, logs de CIAdicionar workflow que só faz build da imagem
Treinamento e handoffComandos, falhas, recuperaçãoEscrever 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”.

#Claude Code #Docker #containers #DevOps #infrastructure
Grátis

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.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.