Actualiza toolkit operativo y documentación
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
# Caso: deploy de oh-daddy en Coolify (2026-09-08)
|
||||
|
||||
**App:** [oh-daddy](https://github.com/KenKaiii/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.
|
||||
Reference in New Issue
Block a user