fix: give Workspace Chat its own public hostname
This commit is contained in:
parent
ff01a5f097
commit
32f76abc9f
6 changed files with 35 additions and 10 deletions
|
|
@ -178,6 +178,6 @@ CHAT_TICKET_SECRET="CHANGE_ME_USE_A_RANDOM_32_BYTE_SECRET"
|
|||
# Internal collab chat listener port (distinct from Hocuspocus/Yjs on 1234)
|
||||
CHAT_PORT=1235
|
||||
# Public WSS endpoint, baked into the web bundle at build time. Rebuild web after changing.
|
||||
NEXT_PUBLIC_CHAT_SERVER_URL="wss://chat.stillwell.cloud"
|
||||
NEXT_PUBLIC_CHAT_SERVER_URL="wss://echodo-chat.stillwell.cloud"
|
||||
|
||||
COLLAB_PORT=1234
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# Domains (Dokploy UI or CT 100 Traefik):
|
||||
# web → echodo.stillwell.cloud (port 3000)
|
||||
# collab → collab.echodo.stillwell.cloud (port 1234)
|
||||
# chat → chat.stillwell.cloud (collab service, CHAT_PORT default 1235)
|
||||
# chat → echodo-chat.stillwell.cloud (collab service, CHAT_PORT default 1235)
|
||||
# opencode (optional) → opencode.stillwell.cloud (port 4096)
|
||||
#
|
||||
# Build (required on ≤8 GB hosts — parallel export OOMs with exit 255):
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
# Workspace Chat — Current Progress
|
||||
|
||||
Updated: 2026-10-29 (homelab go-live + acceptance).
|
||||
Updated: 2026-10-30 (dedicated Chat hostname migration pending rebuild).
|
||||
|
||||
## Status
|
||||
## Hostname correction — pending deployment
|
||||
|
||||
Chat runtime is live on CT 116; operator reports **14/14 acceptance checks passed**. Operator-confirmed CT 102 `echodo` ledger: **24 entries through `0023`**, with required columns/table verified and all `chat_*` tables owned by `echodo`. An earlier copy of this document said `0022–0024`; no `0024` migration exists in this checkout, so that statement is not treated as verified.
|
||||
`chat.stillwell.cloud` belongs to OpenMausBot on CT 117, not Workspace Chat. The operator reports routing to that app has been restored and `echodo-chat.stillwell.cloud` is already an alias on the Workspace Chat Traefik rule.
|
||||
|
||||
The Workspace Chat endpoint is now **`wss://echodo-chat.stillwell.cloud`** (socket path `/chat`). Set `NEXT_PUBLIC_CHAT_SERVER_URL` to that value in CT 116's `/opt/submatter/.env`, rebuild the web image, and recreate web as documented in `docs/deployment-production.md`. Repo examples now use only the dedicated hostname. Deployment and browser verification of the new endpoint are not yet confirmed; a push alone will not update the host's `.env`.
|
||||
|
||||
## Previous go-live evidence (before hostname correction)
|
||||
|
||||
The following records the previous deployment, not verification of the new hostname. Operator reported **14/14 acceptance checks passed**. Operator-confirmed CT 102 `echodo` ledger: **24 entries through `0023`**, with required columns/table verified and all `chat_*` tables owned by `echodo`. An earlier copy of this document said `0022–0024`; no `0024` migration exists in this checkout, so that statement is not treated as verified.
|
||||
|
||||
The deployment evidence below was supplied by the operator and is present in this workspace copy. It was not independently rerun in this reconciliation session; read-only access through PVE stopped at unknown SSH host-key verification.
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ docker compose -f docker/docker-compose.prod.yml \
|
|||
| `AUTH_AUTHENTIK_*` | | Authentik OIDC app `echodo` |
|
||||
| `COLLAB_SERVER_URL` | `wss://collab.echodo.stillwell.cloud` | Server-side |
|
||||
| `NEXT_PUBLIC_COLLAB_SERVER_URL` | `wss://collab.echodo.stillwell.cloud` | **Build arg** — requires image rebuild |
|
||||
| `NEXT_PUBLIC_CHAT_SERVER_URL` | `wss://chat.stillwell.cloud` | **Build arg** — requires web image rebuild; provision DNS/TLS first |
|
||||
| `NEXT_PUBLIC_CHAT_SERVER_URL` | `wss://echodo-chat.stillwell.cloud` | **Build arg** — requires web image rebuild; provision DNS/TLS first |
|
||||
| `CHAT_TICKET_SECRET` | Generate with `openssl rand -base64 32` | Same runtime secret for web and collab; at least 32 characters; never a build arg |
|
||||
| `CHAT_PORT` | `1235` | Second listener inside collab; cannot equal Hocuspocus port `1234` |
|
||||
| `OMNIROUTE_BASE_URL` | `https://omniroute.stillwell.cloud/v1` | Web + worker |
|
||||
|
|
@ -82,7 +82,16 @@ Changing any `NEXT_PUBLIC_*` value requires `bash scripts/deploy-prod.sh build`,
|
|||
Chat runs inside the existing `collab` service on a **separate listener** from Hocuspocus. The worker publishes metadata-only Redis hints; Postgres history and mutation catch-up remain authoritative. Team Chat does not invoke AI agents, and object contexts are not enabled by this deployment.
|
||||
|
||||
1. Set the Chat variables above in `/opt/submatter/.env`. Keep the signing secret server-side; Compose requires a nonempty value, and the application requires at least 32 characters. A missing/short secret disables the listener and makes the dual-listener health check fail.
|
||||
2. Provision `chat.stillwell.cloud` DNS and TLS on CT 100 (canonical browser endpoint). The proxy example also retains `chat.echodo.stillwell.cloud`; a single-level wildcard certificate does not cover that nested hostname. Apply the `echodo-chat` router/service from [`traefik-ct100.example.yml`](../proxmox/ct116/traefik-ct100.example.yml). Traefik supports WebSocket upgrades without a separate service process. If `CHAT_PORT` changes, update the proxy backend port too. Restrict host backend ports to the trusted proxy network.
|
||||
2. Provision `echodo-chat.stillwell.cloud` DNS and TLS on CT 100 (canonical browser endpoint). `chat.stillwell.cloud` belongs to another app: never include it in the Workspace Chat router. Apply the `echodo-chat` router/service from [`traefik-ct100.example.yml`](../proxmox/ct116/traefik-ct100.example.yml). Traefik supports WebSocket upgrades without a separate service process. If `CHAT_PORT` changes, update the proxy backend port too. Restrict host backend ports to the trusted proxy network.
|
||||
|
||||
For the hostname migration, set `NEXT_PUBLIC_CHAT_SERVER_URL=wss://echodo-chat.stillwell.cloud` in CT 116's `/opt/submatter/.env`, then run from `/opt/submatter`:
|
||||
|
||||
```bash
|
||||
docker compose --project-directory /opt/submatter -f docker/docker-compose.prod.yml -f docker/docker-compose.prod.standalone.yml build web
|
||||
docker compose --project-directory /opt/submatter -f docker/docker-compose.prod.yml -f docker/docker-compose.prod.standalone.yml up -d --no-deps web
|
||||
```
|
||||
|
||||
A git push or container restart alone does not change the baked browser URL. Test Workspace Chat inside `https://echodo.stillwell.cloud`; its WebSocket should connect to `wss://echodo-chat.stillwell.cloud/chat`. The WSS endpoint is not a separate chat UI.
|
||||
3. Before rolling out, verify the database target is CT 102 **`echodo`** and inspect `drizzle.__drizzle_migrations`. The operator reports 24 ledger entries through `0023`, verified Chat schema, and ownership of all `chat_*` tables transferred to `echodo`. Do not reapply these migrations; inspect the ledger for any future pending entries. Compare the ledger with `packages/database/migrations/meta/_journal.json`; apply only pending journaled migrations using `pnpm --filter @tasks/database db:migrate` in a checkout with the real `DATABASE_URL` exported securely. Do not print the URL, use `db:push`, or replay historical migrations manually. Take a backup first.
|
||||
4. Verify `0022` added `chat_messages.send_intent_fingerprint` and positive `revision`; verify `0023` added `chat_message_mutations`, its tenant/channel/message foreign keys and indexes, and `chat_channels.next_mutation_sequence`. Do not infer applied schema from TypeScript files. The historical `0017` correction is already local; do not replay it on an initialized database.
|
||||
5. Validate Compose on the deployment host without printing resolved secrets:
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ http:
|
|||
certResolver: letsencrypt
|
||||
|
||||
echodo-chat:
|
||||
rule: Host(`chat.stillwell.cloud`) || Host(`chat.echodo.stillwell.cloud`)
|
||||
rule: Host(`echodo-chat.stillwell.cloud`)
|
||||
entryPoints: [websecure]
|
||||
service: echodo-chat
|
||||
tls:
|
||||
|
|
|
|||
|
|
@ -27,6 +27,16 @@ test("web receives the Chat URL at build time, without baking the signing secret
|
|||
assert.ok(turbo.tasks.build.env.includes("NEXT_PUBLIC_*"));
|
||||
});
|
||||
|
||||
test("Workspace Chat uses its dedicated hostname, not the other app's hostname", () => {
|
||||
assert.match(
|
||||
read(".env.example"),
|
||||
/^NEXT_PUBLIC_CHAT_SERVER_URL="wss:\/\/echodo-chat\.stillwell\.cloud"$/m,
|
||||
);
|
||||
const proxy = read("proxmox/ct116/traefik-ct100.example.yml");
|
||||
assert.ok(proxy.includes("Host(`echodo-chat.stillwell.cloud`)"));
|
||||
assert.ok(!proxy.includes("Host(`chat.stillwell.cloud`)"));
|
||||
});
|
||||
|
||||
test("web and collab receive the same required runtime signing secret", () => {
|
||||
for (const service of [web, collab]) {
|
||||
assert.match(
|
||||
|
|
@ -57,8 +67,8 @@ test("standalone publication matches the configurable Chat listener", () => {
|
|||
|
||||
test("Traefik example routes public Chat TLS to the second collab listener", () => {
|
||||
const proxy = read("proxmox/ct116/traefik-ct100.example.yml");
|
||||
assert.match(proxy, /Host\(`chat\.echodo\.stillwell\.cloud`\)/);
|
||||
assert.match(proxy, /Host\(`chat\.stillwell\.cloud`\)/);
|
||||
assert.match(proxy, /Host\(`echodo-chat\.stillwell\.cloud`\)/);
|
||||
assert.doesNotMatch(proxy, /Host\(`chat\.stillwell\.cloud`\)/);
|
||||
assert.match(proxy, /service: echodo-chat/);
|
||||
assert.match(proxy, /url: "http:\/\/192\.168\.68\.116:1235"/);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue