MUL-6611: docs(self-host): route /health through the proxy, add single-origin example and release-tag note (#7466)
* docs(self-host): route /health through the proxy, add single-origin example and release-tag note
Document the four traps we hit deploying twice from the quickstart alone,
across all four doc locales (en/zh/ja/ko):
- `multica setup` probes <server-url>/health and needs a 200, but the web
image does not proxy /health, so a proxy that forwards everything to the
frontend makes setup fail with "Server not reachable" against a healthy
stack. Add the explicit route to both Caddy examples, a new
troubleshooting section, and a hint at the CLI setup step.
- Add a single-origin reverse-proxy variant (one domain / one port), the
shape small servers actually use, with the daemon-critical paths called
out (/health, /ws).
- The published images track the newest release tag while a plain clone
checks out main. Anyone building the CLI or images from the checkout
should pin the tag first or binaries drift from the containers.
- Add an /api/config verification step: daemon_server_url must print the
public URL, and on Docker Compose < 2.24 FRONTEND_ORIGIN/MULTICA_APP_URL
do not follow FRONTEND_PORT (the ${FRONTEND_PORT} references copied from
.env.example stay literal, refs #6146).
- Note that a curl against /ws returning 400 is expected without a daemon
token; the backend log entry proves the proxy chain works.
* docs(self-host): review fixes — WS 400 attribution, section placement, grep over jq
- The WS-400 note attributed the rejection to daemon-token auth; the actual
reason a bare curl gets 400 is the missing workspace query parameters
(browsers auth by cookie, daemons auth in the first frame after upgrade).
Fixed in all four locales.
- The new troubleshooting section was inserted before the trailing two
paragraphs of the realtime section, swallowing them; moved it after the
reverse-proxy example line.
- daemon_server_url comes from MULTICA_PUBLIC_URL when set (otherwise
MULTICA_APP_URL) and is omitted when both are unset — the verification
note now says so, and the command uses grep instead of jq (jq is not in
the prerequisites list).
- zh: 问题排查 → 故障排查 to match the page title; ja: replaced —— with
the file's established " — " / parenthetical style; linked the matching
row in the Common issues tables to the new anchor in all locales.
* docs(self-host): route /api/daemon/ws in the single-origin example
Daemons dial {server-url}/api/daemon/ws for their long connection, not
/ws — and the web image cannot proxy WebSocket upgrades (which is why
/ws is routed to the backend directly in every example). The single-
origin variant added earlier only routed /ws, leaving the daemon's
handshake to fail through the frontend; the daemon then silently falls
back to polling, with repeated status=400 lines on that path in the
backend log as the only symptom. Add the explicit handle to the
single-origin example in all four locales, and a self-host note in the
troubleshooting WebSocket section.
* docs(self-host): address review — drop Compose version claim, qualify /health wording, bound the curl-400 check
- Remove the unverified 'Docker Compose < 2.24' cutoff; advise setting
FRONTEND_ORIGIN/MULTICA_APP_URL explicitly when /api/config prints
localhost.
- Qualify /health statements for merged #7467: current web releases
forward the path, older ones do not; keep the explicit direct route
(works across releases) and list DNS/TLS/firewall/timeout/5xx as
other probe failures. Covers the Caddy comment, the setup section,
the FAQ row, and the troubleshooting page in en/zh/ja/ko.
- A bare curl 400 on /ws only proves plain HTTP routing reaches the
backend (workspace-param rejection happens before the upgrader);
point at DevTools Network→WS for a real 101 handshake check.
- ja: 転達 → 転送; fix the stale 'Step 1' self-link anchors (en/zh/ja/ko).
* docs(self-host): document the real daemon_server_url precedence and omission
daemonSetupURLsFromEnv resolves the app URL as MULTICA_APP_URL falling
back to FRONTEND_ORIGIN, and omits both daemon fields from /api/config
when that chain is empty — even if MULTICA_PUBLIC_URL is set. The docs
said 'MULTICA_PUBLIC_URL, otherwise MULTICA_APP_URL; empty means
neither is set', which missed the fallback and mis-stated the omission
condition. State all three inputs and the actual condition in
en/zh/ja/ko.
* docs(self-host): include MULTICA_DAEMON_SERVER_URL in the daemon_server_url precedence
daemonSetupURLsFromEnv reads MULTICA_DAEMON_SERVER_URL before
MULTICA_PUBLIC_URL (server/internal/handler/config.go:128), so the
verification note in all four locales was one step short of the real
chain. environment-variables.mdx already documents it in full.
Co-authored-by: multica-agent <github@multica.ai>
---------
Co-authored-by: J <bohan@devv.ai>
Co-authored-by: multica-agent <github@multica.ai> F
Felix021 committed
11ab949dc97fb12b653ef19f2619a09a6eab91c3
Parent: 2167326
Committed by GitHub <noreply@github.com>
on 8/25/2026, 5:07:20 AM