|
| 1 | +# Running OpenConcho in Docker |
| 2 | + |
| 3 | +The `@openconcho/web` SPA can be served from a container. The image is a |
| 4 | +two-stage build: Node + pnpm builds the static bundle, then |
| 5 | +`nginx-unprivileged` serves it on port `8080` as a non-root user. |
| 6 | + |
| 7 | +## Build and run |
| 8 | + |
| 9 | +```bash |
| 10 | +docker build -t openconcho-web . |
| 11 | +docker run --rm -p 8080:8080 openconcho-web |
| 12 | +# → http://localhost:8080 |
| 13 | +``` |
| 14 | + |
| 15 | +Hardened run (read-only filesystem, no added capabilities): |
| 16 | + |
| 17 | +```bash |
| 18 | +docker run --rm -p 8080:8080 \ |
| 19 | + --read-only \ |
| 20 | + --tmpfs /tmp \ |
| 21 | + --tmpfs /var/cache/nginx \ |
| 22 | + --cap-drop ALL \ |
| 23 | + --security-opt no-new-privileges \ |
| 24 | + openconcho-web |
| 25 | +``` |
| 26 | + |
| 27 | +`GET /healthz` returns `200 ok` for container health checks. |
| 28 | + |
| 29 | +## CORS |
| 30 | + |
| 31 | +The desktop app routes HTTP through Rust (`reqwest`), so it is **not** subject |
| 32 | +to browser CORS. The **web build is**: it uses the browser's `fetch`, so every |
| 33 | +request to your Honcho API is cross-origin. Honcho calls are `POST` + |
| 34 | +`application/json` + `Authorization: Bearer`, which the browser always |
| 35 | +**preflights** (`OPTIONS`). You must handle this one of two ways. |
| 36 | + |
| 37 | +### Option 1 — configure Honcho's CORS (recommended) |
| 38 | + |
| 39 | +Honcho is a FastAPI service. Allow the UI's origin via its |
| 40 | +`CORSMiddleware` so preflight and actual requests succeed: |
| 41 | + |
| 42 | +```python |
| 43 | +app.add_middleware( |
| 44 | + CORSMiddleware, |
| 45 | + allow_origins=["http://localhost:8080"], # the OpenConcho origin |
| 46 | + allow_methods=["*"], |
| 47 | + allow_headers=["*"], |
| 48 | +) |
| 49 | +``` |
| 50 | + |
| 51 | +This fits OpenConcho's model directly — the UI keeps using the absolute Honcho |
| 52 | +URL you enter in Settings (stored in `localStorage`). Since you self-host |
| 53 | +Honcho, you control this. |
| 54 | + |
| 55 | +### Option 2 — same-origin reverse proxy (advanced) |
| 56 | + |
| 57 | +Proxy the Honcho API under the same origin that serves the SPA, so the browser |
| 58 | +sees same-origin requests and CORS never applies (the token also never crosses |
| 59 | +origins). Uncomment the `location /honcho/` block in |
| 60 | +[`docker/nginx.conf`](../docker/nginx.conf) and set `proxy_pass` to your Honcho |
| 61 | +host. |
| 62 | + |
| 63 | +Caveat: the Settings form currently validates the base URL as an **absolute** |
| 64 | +URL (`z.string().url()`), so pointing the UI at a relative same-origin path |
| 65 | +(`/honcho`) isn't wired yet. Until that lands, Option 1 is the supported path. |
0 commit comments