5.1 KiB
Container Postgres compartilhado é recriado por outro worktree — mata dev+e2e de todos em voo
Status: rascunho Atualizado em: 2026-08-10 Issue: #605 Priority: P2 Model: composer-2.5 Appetite: ~0,5 dia eng; um outcome verificável
Intenção
O container teqo-postgres-1 é compartilhado por todos os worktrees (compose project pinado -p teqo, um único Postgres em 5432 com todos os bancos teqo_*). Qualquer docker compose -p teqo up executado a partir de qualquer worktree recria o container quando o config_hash do compose difere do que está rodando — o Docker loga com.docker.compose.replace=postgres-1 e o Postgres derruba todas as conexões vivas: dev servers e runs e2e de todos os worktrees em voo morrem com terminating connection due to administrator command (não é failover, é kill).
Medido na sessão OPS29 (2026-08-10): duas runs e2e completas mortas no meio por um worktree vizinho (B195) rodando compose up; 17+ testes falharam com ERR_CONNECTION_REFUSED e Failed query ... terminating connection. db:doctor/preflight não pegam: o restart acontece durante a run, não no boot.
Persona e fluxo
- Persona / contexto: qualquer agente (pool ou humano) rodando
pnpm test:e2eoupnpm devnum worktree enquanto outro worktree executapnpm db:start/docker compose up. - Job principal: que e2e/dev de um worktree sobrevivam à atividade de compose de outro — o container não deve ser recriado sem necessidade, e recriação nunca deve acontecer com conexões vivas.
- Fluxo desejado:
pnpm db:startcom o container já de pé e saudável → no-op (sem recreate); mudança real de config (ex.: bump de imagem) → recria, mas isso é decisão explícita, não efeito colateral de um worktree qualquer. - Anti-goals: não serializar o trabalho dos agentes; não exigir locks manuais; não tocar no
db:startdo container de outro projeto (nextcloud etc.).
Objetivo e aceite
- Rodar
pnpm db:start(ou o compose up equivalente) comteqo-postgres-1já saudável não recria o container nem derruba conexões — verificável:docker inspectmostra o mesmoStartedAtapós o comando. - Uma run e2e local não morre com
terminating connection due to administrator commandpor causa de um worktree vizinho. - O caminho de recriação legítima (config do compose realmente mudou) continua possível por comando explícito.
- Nenhuma mudança no
db:start/db:doctorque afete produção ou o pipeline CI.
Direção no codebase (hipótese)
- Área provável:
docker-compose.yml(anotar/derivar por que o config_hash difere entre worktrees — ex.: paths absolutos ou campos de versão no compose),scripts/db-*.mjs/scripts/lib/*(ondedb:startvive), e/ou um--no-recreate/preflight "já está saudável" nodb:start. - Precedente a olhar:
db:doctor(já diagnostica containers crash-looping e PGDATA compartilhado),guard-dev-db(preflight do dev),scripts/lib/worktree.mjs(slot/porta/bancos — o compose file é o mesmo para todos os worktrees? por que o config_hash divergiu?). - Risco de acoplamento: o compose é usado por todos os worktrees; qualquer mudança de comportamento do
db:startprecisa ser idempotente e não quebrar o provisionamentopnpm worktree next.
Dependências
- Nenhuma. (A família OPS28-30 endereça flaky e2e por seed/compile; este item é o mecanismo de infra paralela — ortogonal.)
Fora de escopo
- Serializar/sincronizar runs e2e entre worktrees (estratégia de escalonamento, não de correção).
- Mexer no
docker-compose.ymlde outros projetos no mesmo host. - CI/produção — o problema é exclusivo do ambiente local de worktrees paralelos.
Rabbit holes
- "Culpar o worktree vizinho": o B195 não fez nada errado —
docker compose upé o comando canônico de start; o defeito é odb:start/compose permitir recreate quando não é necessário. Corte: fix no owner do container (db:start), não na educação dos agentes. - "Lock distribuído de Postgres": sem locks manuais — o container deve ser imutável enquanto saudável; locks só encobririam o recreate.
Questões em aberto
- Por que o config_hash divergiu entre worktrees? (paths? version fields?
com.docker.compose.config_hashdifere por workdir?) — descobrir primeiro, pois pode haver fix mais simples (ex.: pinar o compose para não depender do workdir). - Recriação legítima: como o operador força recreate quando a imagem/config muda de verdade? (ex.:
--force-recreateexplícito ou remover o container antes).
Referências
- Sessão OPS29 (2026-08-10):
docker eventsmostrandocontainer ... (com.docker.compose.project=teqo, com.docker.compose.project.working_dir=/home/fsolla/.cursor/worktrees/teqo/B195-.../docker-compose.yml, com.docker.compose.replace=postgres-1, ...)no meio de duas runs e2e; PostgresStartedAtrecriado às 12:06; 17+ testes falhando comterminating connection due to administrator command/ERR_CONNECTION_REFUSED. AGENTS.md→ "Database & local development":db:start/db:stoppinam-p teqo"para SEMPRE alvo daquele UM container mesmo de um worktree" — a promessa vale para o alvo, não para o recreate.