La réécriture précédente avait remplacé « Do not expose the backend on a public non-loopback address without TLS proxying » par une formulation adossée à `ServerConfig::validate()`. Littéralement vraie, mais pas équivalente : elle troque une OBLIGATION faite à l'opérateur contre une garantie automatique qui n'existe pas. `validate()` valide une configuration, pas la réalité. Rien ne vérifie qu'un proxy est réellement devant le serveur : passer les trois drapeaux en bindant `0.0.0.0` sans aucun proxy satisfait `validate()` et sert du HTTP en clair. La phrase normative est donc rétablie, avec cette limite dite explicitement. Voir #72 : `--trust-reverse-proxy` n'a par ailleurs aucun effet à l'exécution. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
86 lines
3.5 KiB
Markdown
86 lines
3.5 KiB
Markdown
# 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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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.
|
|
That check covers the configuration, not reality: it cannot verify that a proxy
|
|
is actually terminating HTTPS in front of the server. Do not expose the backend
|
|
on a public non-loopback address without TLS proxying.
|
|
|
|
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.
|