Files
IdeA/docs/server-client-mode-remote.md
Blomios 77684ea183 docs(server): clarifier le bind du cas proxy distant et l'origine stricte (#65)
L'exemple du cas « Remote HTTPS » bindait `127.0.0.1` en supposant sans le dire
que le reverse proxy tourne sur la même machine que le serveur. Suivi tel quel
avec un proxy sur une autre machine, il produit un serveur injoignable — ce qui
a réellement induit l'utilisateur en erreur aujourd'hui.

Précise donc : le cas co-localisé vs le cas proxy distant (binder une adresse
joignable par le proxy, lien proxy→serveur en HTTP clair sur le LAN), la
configuration exigée pour tout bind non-loopback, l'égalité stricte de
`--public-origin` contre l'`Origin` de la requête (ouvrir l'UI par le domaine et
non par l'IP, sinon 403), et le pare-feu hôte comme cause de timeout depuis les
autres machines.

Indépendant de #68 et #71 : valeur immédiate, n'attend aucun de leurs lots.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 18:11:56 +02:00

3.3 KiB

IdeA Server/Client Remote Deployment

idea --serve serves the web UI and the API from the same origin. The frontend build must be available as a web root containing index.html.

Local Development

The web build must be produced with the http transport, otherwise the served dist/ is a desktop (Tauri) build that fails in a plain browser with window.__TAURI_INTERNALS__ is undefined. The frontend uses npm, not pnpm:

cd frontend && VITE_TRANSPORT=http npx vite build && cd ..
idea --serve --web-root frontend/dist --app-data-dir "$HOME/.local/share/app.idea.ide"

The default local listener is 127.0.0.1:17373. Loopback development may use plain HTTP; the session cookie is still HttpOnly and SameSite=Strict.

App data directory (must match the desktop app)

idea --serve reads/writes the same on-disk data as the desktop app (projects, profiles, templates). It resolves the app-data directory in this order:

  1. --app-data-dir PATH
  2. IDEA_APP_DATA_DIR
  3. platform default for the Tauri identifier app.idea.ide ($XDG_DATA_HOME/app.idea.ide, else $HOME/.local/share/app.idea.ide)

The resolved path is printed at startup (idea --serve: app data dir = …).

Do not run the desktop app and idea --serve on the same app-data directory at the same time. There is no inter-process lock yet, so two concurrent writers can corrupt state. Close the desktop app while serving.

Packaged Artifact

The release artifact is still a single IdeA binary/AppImage. Packaging must copy the frontend build output (frontend/dist) into the packaged web/ resource next to the binary. idea --serve resolves assets in this order:

  1. --web-root PATH
  2. IDEA_WEB_ROOT
  3. packaged web/, then packaged frontend/dist/
  4. development fallback frontend/dist relative to the current directory

If no index.html is found, the server refuses to start.

Remote HTTPS

Public exposure requires a reverse proxy that terminates HTTPS:

idea --serve \
  --listen 127.0.0.1:17373 \
  --allow-remote \
  --public-origin https://idea.example.com \
  --trust-reverse-proxy

This example is for a reverse proxy running on the same machine as the server. If the proxy runs on another machine, bind an address reachable by that proxy, for example --listen 192.168.1.75:17373, and point the proxy upstream to that address and port. The link from proxy to server is still plain HTTP on the LAN; only the public access is HTTPS.

For any non-loopback bind, keep the full remote HTTPS configuration: --allow-remote, --public-origin https://..., and --trust-reverse-proxy. ServerConfig::validate() rejects a non-loopback bind without it.

The proxy must forward the same origin for the SPA, /api/*, and /api/ws. --public-origin is matched by strict equality against the request Origin: open the UI through the configured domain, not through the server IP, otherwise API calls are rejected with 403.

With a LAN bind, also check the host firewall. If the server is reachable from the local machine but times out from every other host, open the port for the LAN subnet or, preferably, only for the proxy IP. Avoid opening it broadly: the server does not provide its own TLS. Secrets must never be placed in URLs; pairing uses POST /api/pair and then an HttpOnly, Secure, SameSite=Strict session cookie.