Files
Proxmox-Coolify-Manager/docs/casos/oh-daddy-deploy.md
T

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 → db por nombre de servicio; APP_ENCRYPTION_KEY y ADMIN_PASSWORD generados una sola vez (viven solo en .env.local.ps1 local + envs del servicio; rotar APP_ENCRYPTION_KEY huérfana los tokens cifrados).
  • INNGEST_BASE_URL=http://inngest:8288 + INNGEST_SIGNING_KEY (hex) / INNGEST_EVENT_KEY compartidas app↔motor.
  • NEXT_PUBLIC_APP_URL=https://ohdaddy.urieljareth.org (build arg + runtime).
  • La imagen arranca con bash scripts/start.sh (el contract de railway.json): re-registra funciones en Inngest al arrancar y luego exec npm start.
  • Registro manual: curl -X PUT https://ohdaddy.urieljareth.org/api/inngest. Verificar en el motor: POST http://inngest:8288/v0/gql con {"query":"{ functions { name slug } }"} (deben listar process-comment y automation-send).
  • Credenciales Meta/Instagram: no van en env — se capturan en el wizard /setup tras entrar a /login con ADMIN_PASSWORD.

Cómo se desplegó (patrón Solo Leveling, imagen local)

  1. New-CoolifyService.ps1 -NoDeploy creó el servicio (compose base64 + urls → FQDN del servicio app).
  2. Un POST /services/{uuid}/start (que falla en el pull de oh-daddy-app:local, esperado) materializó en disco el compose normalizado con labels Traefik completos, el .env y la red <uuid>.
  3. Build en el server: clone + stacks/oh-daddy/Dockerfile inyectado (multi-stage node:22-alpine, NEXT_PUBLIC_APP_URL como build arg) → oh-daddy-app:local.
  4. docker compose up -d manual + docker network connect <uuid> coolify-proxy.
  5. db/schema.sql aplicado con docker exec -i db-<uuid> psql (idempotente).
  6. PUT /api/inngest público → 200.

Gotchas nuevos (no documentados antes)

  • POST /services/{uuid}/envs da 409 si el compose ya declaró ${VAR}: Coolify auto-crea las claves vacías al parsear. Usar PATCH /services/{uuid}/envs/bulk con {"data":[{key,value,is_literal:true}]}.
  • GET /deploy?uuid= da 405 en 4.3.17 — el trigger válido es POST /services/{uuid}/start.
  • El primer re-sync de Inngest del arranque falla con 503 no available server: start.sh hace el PUT antes de que Traefik considere healthy el contenedor. Es benigno — reintentar el PUT cuando la app esté healthy.
  • El wget de busybox (imagen alpine) soporta --post-data/--header para 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, /health OK.
  • Test-ServiceOnline.ps1 -Fqdn https://ohdaddy.urieljareth.org -Path /login: HTTP 200 + render Chromium limpio (título "Oh Daddy. Comment automations on autopilot"), sin pageerror.
  • Restart policy unless-stopped en 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.