Despliegue
1. Migraciones
Sección titulada «1. Migraciones»bunx --bun drizzle-kit generate # genera SQLbunx --bun drizzle-kit migrate # aplicaSiempre tras migrate (o push en dev), aplicar los triggers:
psql "$DATABASE_URL" -f src/db/triggers.sqlSin este paso faltan los triggers de integridad cross-evento y de inmutabilidad de la bitácora: la app corre pero sus garantías no.
2. Arranque
Sección titulada «2. Arranque»bun install --productionbun src/index.ts # escucha en :5000 (o $PORT)En producción:
CORREO_PROVEEDOR=smtpcon credenciales reales.- Los cuatro secretos llenos (
BOLETO_HMAC_SECRETfall-fast sin él). TRUST_PROXY=truedetrás de proxy/LB.CRON_ENABLED=trueen una sola réplica;falseen el resto.CORS_ORIGINcon los orígenes del front.
3. Documentación estática
Sección titulada «3. Documentación estática»El manual se compila con Astro/Starlight a docs/dist y lo sirve la
misma API en la raíz:
cd docsbun installbun run build # genera docs/dist| URL | Contenido |
|---|---|
/ |
Este manual (si docs/dist existe) |
/openapi |
Referencia de endpoints (Scalar) |
/health |
Salud: proceso + base de datos |
/llms.txt |
Versiones del manual para LLMs; ver llms.txt para LLMs |
Si docs/dist no existe, la API responde 404 en / y todo lo demás
funciona igual (las rutas de la API tienen prioridad sobre el estático).
El build hornea la URL pública del sitio (site en
docs/astro.config.mjs): en producción debe coincidir con APP_URL,
o las URLs absolutas del llms.txt y del sitemap apuntarán a otro host.
Para desarrollar el sitio con recarga:
cd docs && bun run dev # http://localhost:43214. Verificación post-deploy
Sección titulada «4. Verificación post-deploy»curl -s localhost:5000/health # {"status":"ok",...}curl -s localhost:5000/openapi/json | head -c 100 # especificacióncurl -sI localhost:5000/ # 200 si docs construidasChecklist de release (local, antes de subir):
bunx tsc --noEmit --moduleResolution bundler --module ES2022 --target ES2021 --strict --skipLibCheck --types bun-typesbunx biome lint ./srcbun test --preload ./test/setup.tsbunx drizzle-kit check5. Operación continua
Sección titulada «5. Operación continua»- Logs: arranque (cron programados), warnings
[seguridad]si falta algún secreto, y[cron] <job> oken cada corrida. - Bitácora:
GET /auditoria/+POST /auditoria/verificarperiódico (ver Auditoría). - Cola de correos: vigila
GET /notificaciones/?estado=fallido.
6. Pipeline por ramas (GitHub Actions)
Sección titulada «6. Pipeline por ramas (GitHub Actions)»dev despliega al VPS de pruebas; master, a producción:
ci.ymlcorre en ambas ramas: tipos, lint, schema, e2e con Postgres de CI y arranque sin DB.deploy-staging.ymltras CI verde endev: por SSH hacegit pulldedev→drizzle-kit migrate(opushsi aún no hay.sql) →psql -f src/db/triggers.sql→docker compose -f compose.staging.yml up -d --build→ verificaGET /health.deploy-prod.ymles manual hasta que exista el servidor (mismo flujo con.env.prodycompose.prod.yml: puerto solo en loopback, el TLS lo da el reverse proxy del host, conTRUST_PROXY=true).
Detalles:
- Solo la API va en Docker; Postgres corre bare-metal en cada host y el
contenedor lo alcanza vía
host.docker.internal:5432(vercompose.*.yml). Los pasos de migrate/triggers corren en el host con esa URL traducida alocalhost. - Los
.env.staging/.env.prodviven en/opt/pisa-apide cada servidor (nunca en git); en GitHub solo hay secrets de infra:VPS_STAGING_*yVPS_PROD_*(HOST,USER,SSH_KEY,PORT). - Disparo manual: Actions → Deploy staging/prod → Run workflow.
drizzle/está versionado: commitea cada migración generada para que CI y los deploys apliquen el mismo SQL.
Siguiente paso
Sección titulada «Siguiente paso»→ Tests