Use Cases (Atualizado: 01/06/2026)

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.

Guia prático de Claude Code e Docker Compose: App local, Postgres, Redis e Worker

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

UsoPor que Compose ajudaAtenção
Desenvolvimento localUm comando inicia app, DB, Redis e workerPerformance de mount varia por sistema operacional
Testes de integraçãoDB e Redis de teste sobem sob demandaPortas e cache em CI precisam ser explícitos
Onboarding.env.example e make setup padronizam o caminhoNunca coloque secrets reais nos exemplos
ProduçãoPode servir para ferramentas internas pequenasExige 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.

#Claude Code #Docker #Docker Compose #desenvolvimento local #PostgreSQL #Redis
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.