4.7 KiB
Caso: deploy de oh-daddy en Coolify (2026-09-08)
App: oh-daddy — automatización de
comentarios de Instagram/Facebook (keyword → respuesta pública + DM). Next.js 16,
postgres (sin ORM), Inngest self-hosted como cola. El repo está diseñado
para Railway (railway.json, scripts/railway-setup.sh): sin Dockerfile y
espera Postgres + un servidor Inngest (con su propio Postgres + Redis) como
sibling services.
Resultado: https://ohdaddy.urieljareth.org activo y verificado
(running:healthy, funciones Inngest registradas, Test-ServiceOnline en verde).
Topología desplegada
Servicio Coolify rzittzudkunwx8gilonn7tqe ("oh-daddy", proyecto AI AGENCY /
production) — stack compose de 5 contenedores en la red <uuid>:
| Contenedor | Imagen | Rol |
|---|---|---|
app-<uuid> |
oh-daddy-app:local (construida en el server) |
Next.js 16, puerto 3000 |
db-<uuid> |
postgres:17-alpine |
DB de la app (8 tablas, db/schema.sql) |
inngest-<uuid> |
inngest/inngest:v1.44.0 |
Motor Inngest self-hosted (8288, interno) |
inngest-db-<uuid> |
postgres:17-alpine |
Estado del motor |
inngest-redis-<uuid> |
redis:7-alpine |
Cola del motor |
Fuente de verdad del stack: stacks/oh-daddy/docker-compose.coolify.yml (sin
secretos; llegan por envs del servicio). Redeploy: scripts/apps/Deploy-OhDaddy.ps1.
Wiring de la app (replica el contract de railway-setup.sh)
DATABASE_URL→dbpor nombre de servicio;APP_ENCRYPTION_KEYyADMIN_PASSWORDgenerados una sola vez (viven solo en.env.local.ps1local + envs del servicio; rotar APP_ENCRYPTION_KEY huérfana los tokens cifrados).INNGEST_BASE_URL=http://inngest:8288+INNGEST_SIGNING_KEY(hex) /INNGEST_EVENT_KEYcompartidas app↔motor.NEXT_PUBLIC_APP_URL=https://ohdaddy.urieljareth.org(build arg + runtime).- La imagen arranca con
bash scripts/start.sh(el contract derailway.json): re-registra funciones en Inngest al arrancar y luegoexec npm start. - Registro manual:
curl -X PUT https://ohdaddy.urieljareth.org/api/inngest. Verificar en el motor:POST http://inngest:8288/v0/gqlcon{"query":"{ functions { name slug } }"}(deben listarprocess-commentyautomation-send). - Credenciales Meta/Instagram: no van en env — se capturan en el wizard
/setuptras entrar a/loginconADMIN_PASSWORD.
Cómo se desplegó (patrón Solo Leveling, imagen local)
New-CoolifyService.ps1 -NoDeploycreó el servicio (compose base64 +urls→ FQDN del servicioapp).- Un
POST /services/{uuid}/start(que falla en el pull deoh-daddy-app:local, esperado) materializó en disco el compose normalizado con labels Traefik completos, el.envy la red<uuid>. - Build en el server: clone +
stacks/oh-daddy/Dockerfileinyectado (multi-stage node:22-alpine,NEXT_PUBLIC_APP_URLcomo build arg) →oh-daddy-app:local. docker compose up -dmanual +docker network connect <uuid> coolify-proxy.db/schema.sqlaplicado condocker exec -i db-<uuid> psql(idempotente).PUT /api/inngestpúblico → 200.
Gotchas nuevos (no documentados antes)
POST /services/{uuid}/envsda 409 si el compose ya declaró${VAR}: Coolify auto-crea las claves vacías al parsear. UsarPATCH /services/{uuid}/envs/bulkcon{"data":[{key,value,is_literal:true}]}.GET /deploy?uuid=da 405 en 4.3.17 — el trigger válido esPOST /services/{uuid}/start.- El primer re-sync de Inngest del arranque falla con
503 no available server:start.shhace el PUT antes de que Traefik considere healthy el contenedor. Es benigno — reintentar el PUT cuando la app esté healthy. - El
wgetde busybox (imagen alpine) soporta--post-data/--headerpara golpear el gql del motor desde el contenedor app.
Verificación (2026-09-08)
GET /resources→running:healthy; 5 contenedores healthy; DNS entre hermanos OK (db,inngest,inngest-db,inngest-redis).- Motor:
{"data":{"functions":[{"name":"automation-send"...},{"name":"process-comment"...}]}}, app "oh-daddy" registrada,/healthOK. Test-ServiceOnline.ps1 -Fqdn https://ohdaddy.urieljareth.org -Path /login: HTTP 200 + render Chromium limpio (título "Oh Daddy. Comment automations on autopilot"), sinpageerror.- Restart policy
unless-stoppeden los 5 contenedores (sobreviven reinicios del LXC junto con el autostart de Docker).
Pendiente humano
Entrar a https://ohdaddy.urieljareth.org/login con ADMIN_PASSWORD (única
copia en plaintext: el reporte del deploy / .env.local.ps1) y completar el
wizard /setup con las credenciales de la app de Meta.