mirror of
https://origin.cursor.com/mrdevmx/panels.git
synced 2026-10-09 15:33:17 +00:00
Compare commits
2 commits
0373c5def1
...
ce3e704ab7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce3e704ab7 | ||
|
|
ccf86c5b2e |
2 changed files with 36 additions and 8 deletions
30
api/main.ts
30
api/main.ts
|
|
@ -1252,22 +1252,36 @@ registerPayrollRoutes(app);
|
|||
|
||||
const port = config.port;
|
||||
|
||||
function startup(name: string, p: Promise<unknown>): Promise<unknown> {
|
||||
return p.then(() => {
|
||||
console.log(`[startup] ok ${name}`);
|
||||
}).catch((e: unknown) => {
|
||||
const msg = e instanceof Error ? e.message : String(e);
|
||||
console.error(`[startup] FAIL ${name}: ${msg}`);
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
// Fail-fast (Fase 7): antes con SQLite la app "siempre arrancaba" (creaba
|
||||
// el archivo si no existía). Con Postgres/Redis, si alguna de las 5
|
||||
// conexiones no responde al arrancar, es mejor fallar ruidosamente que
|
||||
// dejar que el primer request autenticado descubra el problema.
|
||||
await Promise.all([
|
||||
pingCoreDb(),
|
||||
pingPlatformDb(),
|
||||
pingRedis().then((r) => {
|
||||
if (!r.iam || !r.core) throw new Error("Redis (iam/core) no responde");
|
||||
}),
|
||||
pingStorage().then((s) => {
|
||||
if (!s.ok) throw new Error("Storage (Contabo o disco local) no responde");
|
||||
startup("postgres core (DATABASE_URL_CORE)", pingCoreDb()),
|
||||
startup("postgres platform (DATABASE_URL_PLATFORM)", pingPlatformDb()),
|
||||
startup("redis iam+core", pingRedis().then((r) => {
|
||||
if (!r.iam || !r.core) {
|
||||
throw new Error(
|
||||
`Redis no responde (iam=${r.iam} core=${r.core}). REDIS_URL_* debe usar el hostname de Redis URL (internal), no el UUID de Postgres.`,
|
||||
);
|
||||
}
|
||||
})),
|
||||
startup("storage S3/R2", pingStorage().then((s) => {
|
||||
if (!s.ok) throw new Error("Storage no responde (HeadBucket R2 o disco local)");
|
||||
if (!config.isDev && !s.configured) {
|
||||
throw new Error("S3_ENDPOINT/S3_BUCKET/S3_* son obligatorios fuera de desarrollo");
|
||||
}
|
||||
}),
|
||||
})),
|
||||
]);
|
||||
|
||||
Deno.serve({ port, hostname: "0.0.0.0" }, app.fetch);
|
||||
|
|
|
|||
|
|
@ -120,6 +120,20 @@ Ejemplo: `sudo docker logs migrate-pdyrt8ccp804tfmutefau0k6-052025710094`. `Unkn
|
|||
|
||||
El `docker stop … No such container` del helper de Coolify es ruido de limpieza, no la causa. El build de imágenes puede ser OK y el deploy igual falla en `migrate`.
|
||||
|
||||
### `dependency api failed to start` / `api is unhealthy`
|
||||
|
||||
Liquibase ya corrió si ves `migrate … Exited` y acto seguido `api … Starting`. La API **no llega a escuchar** si Redis, S3 o los roles `_app` fallan (fail-fast antes de `Deno.serve`). Coolify entonces marca unhealthy en 1–2 s.
|
||||
|
||||
```bash
|
||||
sudo docker logs api-<uuid>-<timestamp>
|
||||
```
|
||||
|
||||
Busca `[startup] FAIL …`. Causas típicas:
|
||||
|
||||
- **Redis:** `REDIS_URL_IAM` / `REDIS_URL_CORE` con el UUID de **Postgres**. Redis tiene el suyo (Redis URL internal).
|
||||
- **S3/R2:** faltan `S3_*` o HeadBucket falla (token Account API, Object Read & Write, bucket correcto, `S3_REGION=auto`).
|
||||
- **Postgres `_app`:** Liquibase usa `*_OWNER`; el runtime usa `DATABASE_URL_PLATFORM`, `DATABASE_URL_IAM`, `DATABASE_URL_CORE` (passwords distintos).
|
||||
|
||||
### Coolify pide `PLATFORM_OWNER_PASSWORD`, `IAM_APP_PASSWORD`, `*_REDIS_PASSWORD`…
|
||||
|
||||
Eso sale de **Reload Compose** mezclando el overlay de desarrollo. En producción **no las rellenes**. En el recurso: Compose file = `docker-compose.yml` únicamente. Borra esas 8 variables si Coolify las marcó Required. Siguen haciendo falta las URLs completas (`DATABASE_URL_*`, `REDIS_URL_*`).
|
||||
|
|
|
|||
Loading…
Reference in a new issue