Compare commits

..

1 Commits

Author SHA1 Message Date
tes 9e1c097f2e Document two Coolify gotchas hit while adding the external-apps user
- docker_compose_domains regresses to defaults on some deploys because
  the stored value lacks the 'name' field; recovery is a PATCH with the
  array form followed by a redeploy.
- The 'nats' npm package cannot connect over wss:// from Node; use
  'nats.ws' + 'ws' polyfill instead.
2026-08-26 18:09:57 +00:00
+15
View File
@@ -135,6 +135,21 @@ To add a second user (e.g. a scoped app account), edit the `authorization.users`
- **Coolify's deploy status ≠ container health.** A deploy returning `status: "finished"` from `/api/v1/deployments/…` just means the build + `docker compose up -d` step ran to completion. If the container then crash-loops (e.g. bad `nats-server.conf`), the deploy is still "finished" but the app's `/api/v1/applications/{uuid}` shows `status: "restarting:unknown"` and `/api/v1/applications/{uuid}/logs` returns `Application is not running.` — no runtime logs via API. Fall back to `docker logs <container-name>` on the Coolify host to see why the process is dying. Container name pattern: `nats-<app-uuid>-<random>`. - **Coolify's deploy status ≠ container health.** A deploy returning `status: "finished"` from `/api/v1/deployments/…` just means the build + `docker compose up -d` step ran to completion. If the container then crash-loops (e.g. bad `nats-server.conf`), the deploy is still "finished" but the app's `/api/v1/applications/{uuid}` shows `status: "restarting:unknown"` and `/api/v1/applications/{uuid}/logs` returns `Application is not running.` — no runtime logs via API. Fall back to `docker logs <container-name>` on the Coolify host to see why the process is dying. Container name pattern: `nats-<app-uuid>-<random>`.
- **`docker_compose_domains` regresses after config-touching deploys.** The stored value on this app is `{"nats":{"domain":"https://nats.tes.gd:8080"}}` — object-keyed, no `name` field. Coolify's Traefik-label generator wants each entry to carry an explicit `name`; without it, on some deploys the labels fall back to defaults (`Host(<app-uuid>.tes.gd)` on port 80) and `wss://nats.tes.gd` stops routing to the container even though the container itself is `running:healthy`. Symptom: `curl https://nats.tes.gd/` returns a 404 or lands on an unrelated service; NATS logs show `websocket handshake error: invalid value for header 'Upgrade'` for requests that do slip through. Fix by PATCHing with the **array form** (per `deploying-to-coolify-via-api` skill), then redeploying:
```bash
APP_UUID=$(jq -r '.app.uuid' deploy.json)
curl -sS -X PATCH "$COOLIFY_URL/api/v1/applications/$APP_UUID" \
-H "Authorization: Bearer $COOLIFY_KEY" -H 'Content-Type: application/json' \
-d "$(jq -c '.app.docker_compose_domains | to_entries | map({name: .key, domain: .value.domain}) | {docker_compose_domains: .}' deploy.json)"
curl -sS -X POST "$COOLIFY_URL/api/v1/deploy?uuid=$APP_UUID" \
-H "Authorization: Bearer $COOLIFY_KEY"
```
Verify by curling `https://nats.tes.gd/`: you want `HTTP 400 Bad Request` with a `sec-websocket-version: 13` response header (NATS's WS handler answering a non-Upgrade request). Anything else means Traefik still isn't pointed at the NATS container.
- **`nats` npm package doesn't speak WebSocket from Node.** From Node, `import { connect } from "nats"` with `servers: "wss://…"` fails with `CONNECTION_REFUSED` — that package is TCP-only from Node. For Node-side WebSocket clients use `nats.ws` with a `ws` polyfill (see the "With `nats.js` / `nats.ws`" snippet earlier in this file); in the browser `nats.ws` works directly.
## Files in this repo ## Files in this repo
| File | Purpose | | File | Purpose |