Guia prático de Claude Code e Docker Compose: App local, Postgres, Redis e Worker
Guia prático para montar com Claude Code um Docker Compose com app, Postgres, Redis, worker e healthchecks.
Docker Compose é o mapa de um ambiente local com aplicação, PostgreSQL, Redis e worker em segundo plano. A documentação oficial do Docker Compose descreve a ferramenta como uma forma de definir e executar aplicações com múltiplos contêineres, gerenciando serviços, redes e volumes em um arquivo YAML.
Isso combina muito bem com Claude Code. Em vez de pedir de forma vaga “crie um ambiente Docker”, forneça arquivos reais para ele revisar: compose.yaml, Dockerfile, .env.example e Makefile. O resultado é mais fácil de reproduzir, revisar e ensinar ao time.
Quando Masa testou esse padrão em um pequeno projeto Next.js com queue worker, o que mais ajudou não foi um prompt sofisticado. O ganho veio dos detalhes: esperar o Postgres ficar pronto, persistir Redis, proteger node_modules e alinhar comandos de migration/test com CI.
Este guia monta um exemplo copiável com app + PostgreSQL + Redis + worker. Compose é excelente para desenvolvimento local, testes de integração e onboarding. Produção é outra conversa: orquestração, secrets, monitoramento, backup, segurança e custo precisam de revisão separada.
Arquitetura
flowchart LR
Dev["Developer"] --> App["app: web server"]
App --> Pg["postgres: database"]
App --> Redis["redis: cache and queue"]
Worker["worker: background jobs"] --> Pg
Worker --> Redis
App --> Volume["named volume: node_modules"]
Pg --> PgVol["named volume: postgres_data"]
Redis --> RedisVol["named volume: redis_data"]
app serve a aplicação web. worker processa tarefas em segundo plano como e-mails, webhooks, imagens ou jobs de fila. postgres e redis recebem healthchecks para indicar prontidão real, não apenas contêiner iniciado.
Para sintaxe oficial, use Compose file reference e services reference. Também vale instruir Claude Code a usar essas referências para evitar exemplos antigos de docker-compose.
Onde Compose se encaixa
| Uso | Por que Compose ajuda | Atenção |
|---|---|---|
| Desenvolvimento local | Um comando inicia app, DB, Redis e worker | Performance de mount varia por sistema operacional |
| Testes de integração | DB e Redis de teste sobem sob demanda | Portas e cache em CI precisam ser explícitos |
| Onboarding | .env.example e make setup padronizam o caminho | Nunca coloque secrets reais nos exemplos |
| Produção | Pode servir para ferramentas internas pequenas | Exige revisão de segurança, recuperação, escala e custo |
A fronteira com produção é essencial. Compose cria o mesmo ambiente de trabalho em cada máquina. Para produção, compare com ECS, Kubernetes, Cloud Run, Fly.io, Render ou a plataforma existente. Peça ao Claude Code para listar restrições de migração, não para transformar automaticamente o arquivo local em deploy.
compose.yaml copiável
O exemplo assume Node.js ou Next.js. Troque npm run dev, npm run worker:dev e os scripts de migration pelos comandos do seu package.json.
# compose.yaml
services:
app:
build:
context: .
dockerfile: Dockerfile
target: dev
command: npm run dev -- --hostname 0.0.0.0
ports:
- "3000:3000"
env_file:
- .env
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?schema=public
REDIS_URL: redis://redis:6379
volumes:
- .:/workspace
- node_modules:/workspace/node_modules
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "node -e \"fetch('http://127.0.0.1:3000/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""]
interval: 10s
timeout: 5s
retries: 12
start_period: 20s
worker:
build:
context: .
dockerfile: Dockerfile
target: dev
command: npm run worker:dev
env_file:
- .env
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?schema=public
REDIS_URL: redis://redis:6379
volumes:
- .:/workspace
- node_modules:/workspace/node_modules
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
postgres:
image: postgres:16-alpine
ports:
- "5432:5432"
env_file:
- .env
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./docker/postgres/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 5s
timeout: 5s
retries: 10
redis:
image: redis:7-alpine
command: ["redis-server", "--appendonly", "yes"]
ports:
- "6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
volumes:
node_modules:
postgres_data:
redis_data:
Três detalhes evitam muitos problemas. Dentro da rede Compose, contêineres usam nomes de serviço: postgres:5432 e redis:6379, não localhost. node_modules fica em named volume para o bind mount do código não apagar dependências instaladas no contêiner. O duplo cifrão no healthcheck do Postgres deixa a variável para o shell do contêiner.
Dockerfile
Um Dockerfile com stages de desenvolvimento, build e produção costuma ser mais simples de manter.
# Dockerfile
# syntax=docker/dockerfile:1
FROM node:22-alpine AS base
WORKDIR /workspace
ENV NEXT_TELEMETRY_DISABLED=1
COPY package*.json ./
RUN npm ci
FROM base AS dev
EXPOSE 3000
CMD ["npm", "run", "dev", "--", "--hostname", "0.0.0.0"]
FROM base AS build
COPY . .
RUN npm run build
FROM node:22-alpine AS production
WORKDIR /workspace
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=build /workspace/.next ./.next
COPY --from=build /workspace/public ./public
USER node
EXPOSE 3000
CMD ["npm", "start"]
O stage dev não copia o código fonte porque Compose faz o mount. O stage build copia o repositório inteiro para que CI e a imagem de produção não dependam do estado local.
.env.example
Commit .env.example, não .env. O arquivo de exemplo mostra a forma da configuração sem expor credenciais reais.
# .env.example
POSTGRES_USER=app
POSTGRES_PASSWORD=app_password
POSTGRES_DB=app_development
DATABASE_URL=postgresql://app:app_password@postgres:5432/app_development?schema=public
REDIS_URL=redis://redis:6379
NODE_ENV=development
PORT=3000
env_file envia variáveis aos contêineres. A interpolação do arquivo Compose também lê o .env do projeto. Mantenha os nomes e valores coerentes para evitar bugs difíceis de ver.
Makefile e comandos pontuais
Um Makefile pequeno reduz ambiguidade. Se o time não usa make, mova os comandos para scripts do package.json.
COMPOSE = docker compose --env-file .env -f compose.yaml
.PHONY: setup up up-d down restart logs ps app-shell db-shell redis-cli migrate seed test lint clean
setup:
cp .env.example .env
$(COMPOSE) build
up:
$(COMPOSE) up --build
up-d:
$(COMPOSE) up -d --build
down:
$(COMPOSE) down
restart:
$(COMPOSE) restart app worker
logs:
$(COMPOSE) logs -f app worker postgres redis
ps:
$(COMPOSE) ps
app-shell:
$(COMPOSE) exec app sh
db-shell:
$(COMPOSE) exec postgres psql -U app -d app_development
redis-cli:
$(COMPOSE) exec redis redis-cli
migrate:
$(COMPOSE) run --rm app npm run db:migrate
seed:
$(COMPOSE) run --rm app npm run db:seed
test:
$(COMPOSE) run --rm app npm test
lint:
$(COMPOSE) run --rm app npm run lint
clean:
$(COMPOSE) down --volumes --remove-orphans
Use exec para contêineres já em execução. Use run --rm para tarefas pontuais como lint, test, migration e seed. Essa diferença aproxima local e CI.
Prompt de revisão para Claude Code
A página Claude Code common workflows recomenda dividir o trabalho em tarefas focadas: entender, editar, testar e revisar. Use a mesma lógica para Compose.
Revise a configuração Docker Compose deste repositório.
Arquivos:
- compose.yaml
- Dockerfile
- .env.example
- package.json
- workflows de CI, se existirem
Verifique:
1. app + postgres + redis + worker rodam localmente
2. healthchecks e depends_on foram usados corretamente
3. named volumes e bind mounts são seguros
4. .env.example não contém secrets reais
5. existem comandos pontuais para migrate, seed, test e lint
6. riscos em CI: portas, cache, permissões e espera de serviços
7. o que revisar antes de usar este padrão em produção
Restrições:
- seguir o framework e package manager existentes
- deixar grandes refactors como proposta
- se editar, explicar o motivo e o comando de verificação
Guarde esse prompt perto do CLAUDE.md para repetir o padrão de revisão. Leia também o guia de Dev Container e o guia de CI/CD.
Casos práticos
O primeiro caso é onboarding no primeiro dia. Se a pessoa copia .env.example e executa make up, app, DB, Redis e worker sobem sem instalar cada serviço manualmente.
O segundo caso é validar filas localmente. E-mails, imagens, webhooks de pagamento e notificações costumam viver no worker. Colocar worker no Compose permite reproduzir jobs reais.
O terceiro caso é estabilizar testes de integração. Muitos bugs passam com SQLite e falham em Postgres. Compose aproxima o teste do banco real e revela diferenças de SQL, migration e fila mais cedo.
O quarto caso é revisão de infraestrutura com Claude Code. Humanos deixam passar localhost, volumes antigos, healthchecks ausentes e secrets em exemplos. Um prompt reutilizável transforma isso em checklist.
Armadilhas comuns
O erro mais comum é conectar ao DB usando localhost de dentro do contêiner app. Na rede Compose, nomes de serviço são hosts. Use postgres e redis.
Outro erro é tratar depends_on como garantia completa de prontidão. condition: service_healthy ajuda, mas a app ainda precisa de retry, e o worker não deve executar tarefas críticas antes das migrations.
Named volumes antigos também confundem. Se o schema mudou e postgres_data ficou, seu estado local pode não representar o repositório. Use make clean para recomeçar, sabendo que dados locais serão apagados.
Não coloque API keys reais em .env.example. Use valores como app_password ou replace_me; secrets reais ficam em Docker secrets, cloud secret manager ou secrets de CI.
Por fim, não trate o Compose local como plano de produção sem revisão. Produção exige TLS, exposição de rede, backup de DB, persistência Redis, monitoramento, scan de vulnerabilidades, origem de imagens, permissões e custo.
Treinamento e templates ClaudeCodeLab
Para adaptar essa base ao seu repositório, comece pelos products and templates do ClaudeCodeLab para padronizar CLAUDE.md, prompts de revisão e runbooks. Se o problema é adoção em equipe, diferenças do Docker Desktop, CI/CD, permissões ou onde Compose termina e orquestração começa, use a página de training and consultation.
Referências oficiais: Docker Compose, Compose file reference, services reference e Claude Code common workflows.
Depois de testar o conteúdo deste artigo, o projeto de Masa conseguiu iniciar app, Postgres, Redis e worker com make up, e os healthchecks reduziram a corrida em que a app sobe antes do banco. O ponto sensível foram named volumes antigos: eles podem fazer uma migration parecer quebrada ou corrigida pelo motivo errado. A conclusão prática é que Compose é uma base forte para desenvolvimento local, mas produção ainda precisa de revisão separada de segurança, operação, recuperação e custo.
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.