Imagem Docker e compose reproduzíveis para homologação
Não existia nenhum artefato de deploy: sem Dockerfile, sem compose, sem pin de Node. O runbook pedia `npm run start` e `npm run worker` à mão, o que não é um ambiente reproduzível, e o worker dependia de `tsx`, uma devDependency, que `npm ci --omit=dev` removeria. - Dockerfile multistage. Web e worker saem da mesma imagem: mesmo código, mesmas dependências, só o subcomando difere. - `tsx` foi para `dependencies`. Conferido em diretório limpo: os 13 pacotes externos que src e scripts usam existem no install de produção. - A sobreposição das duas árvores de node_modules é segura e foi medida: 318 pacotes em produção contra 153 traçados, zero divergência de versão entre os compartilhados, e 3 que existem só na traçada, que o COPY mescla sem remover. O package.json do standalone não é sobrescrito. - Entrypoint com subcomandos, que garante `node --import tsx` em todos os scripts. Usar `node` direto convidaria de volta o defeito do SIGTERM. - Healthcheck de liveness na web e de heartbeat no worker. - Compose local reproduz a topologia com Postgres e Redis de verdade. Compose de homologação não declara Postgres (é o banco gerenciado), usa Redis isolado com senha e volume próprios, publica porta só em 127.0.0.1 e tem nome de projeto, rede e volume exclusivos. Nenhum serviço de outro aplicativo do ecossistema é declarado, tocado ou reiniciado. - `.env.staging.example` sem segredo, `.nvmrc`, `engines` e `packageManager`. - `config/staging-seed.json` e `.env.staging` no gitignore. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ca8a1112f0
commit
dea510c3b4
11 files changed
+598
-28
No files matched your search
@@ -0,0 +1,47 @@
|
||||
#!/bin/sh
|
||||
# Entrada única da imagem. Mantém os comandos curtos e garante que todos os
|
||||
# scripts operacionais rodem no MESMO processo do contêiner.
|
||||
#
|
||||
# Por que `node --import tsx` e não o CLI do tsx: o CLI cria um processo filho,
|
||||
# e o SIGTERM do `docker stop` pararia no pai. O worker precisa receber o sinal
|
||||
# para esperar o tick corrente e liberar o lock no `finally`.
|
||||
set -eu
|
||||
|
||||
TSX="--import=tsx"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
uso: entrypoint.sh <comando> [args]
|
||||
|
||||
web servidor Next (saída standalone)
|
||||
worker processo de fila
|
||||
migrate [--dry-run]
|
||||
seed-staging
|
||||
flag <workspace_id> on|off
|
||||
cleanup
|
||||
verify-config
|
||||
check-bucket
|
||||
smoke
|
||||
worker-health confere o heartbeat do worker (healthcheck do contêiner)
|
||||
exec <cmd...> qualquer outro comando
|
||||
EOF
|
||||
}
|
||||
|
||||
cmd="${1:-web}"
|
||||
[ $# -gt 0 ] && shift || true
|
||||
|
||||
case "$cmd" in
|
||||
web) exec node server.js ;;
|
||||
worker) exec node $TSX scripts/worker.ts ;;
|
||||
migrate) exec node $TSX scripts/migrate.ts "$@" ;;
|
||||
seed-staging) exec node $TSX scripts/seed-staging.ts "$@" ;;
|
||||
flag) exec node $TSX scripts/set-flag.ts "$@" ;;
|
||||
cleanup) exec node $TSX scripts/cleanup-temp.ts "$@" ;;
|
||||
verify-config) exec node $TSX scripts/verify-config.ts ;;
|
||||
check-bucket) exec node $TSX scripts/check-bucket.ts ;;
|
||||
smoke) exec node $TSX scripts/smoke-staging.ts ;;
|
||||
worker-health) exec node docker/worker-health.mjs ;;
|
||||
exec) exec "$@" ;;
|
||||
-h|--help|help) usage ;;
|
||||
*) echo "comando desconhecido: $cmd" >&2; usage >&2; exit 2 ;;
|
||||
esac
|
||||
Reference in new issue
Block a user