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.
Artigos relacionados
Microservices com Claude Code: limites, APIs, Compose e testes
Guia de microservices com Claude Code: limites, contratos API, dados, Docker Compose, observabilidade, testes e rollout.
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 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.