SIGN IN SIGN UP

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