From bf8a6e35fdd72a0fe29cd5a30bb020f63dd9919f Mon Sep 17 00:00:00 2001 From: voidborne-d <258577966+voidborne-d@users.noreply.github.com> Date: Sun, 17 May 2026 16:39:54 +0800 Subject: [PATCH] docs(deployment): match docker run gateway example to docker-compose.yml (refs #3873) The `docker run` example for `gateway` in `docs/deployment.md` had drifted from the canonical configuration in `docker-compose.yml`: - It omitted the security flags that `docker-compose.yml` already declares (`cap_drop: ALL` + `cap_add: SYS_ADMIN` + unconfined apparmor/seccomp). These are required whenever `tools.exec.sandbox: "bwrap"` is enabled, because bwrap needs CAP_SYS_ADMIN for user namespaces; without them bwrap exits with `clone3: Operation not permitted` and exec tools silently fail. - It omitted `-p 8765:8765`, even though both the bundled `docker-compose.yml` and `Dockerfile` (`EXPOSE 18790 8765`) already expose the WebSocket channel / WebUI port; users following the docs would get a reachable gateway health endpoint but an unreachable WebUI. This change keeps the two paths in sync so anyone reading deployment.md and using `docker run` directly gets the same security posture and port surface as the Compose path. Also adds a short `!IMPORTANT` note documenting that `gateway.host` and `channels.websocket.host` default to `127.0.0.1` (set in `nanobot/config/schema.py:GatewayConfig`). Docker `-p` cannot forward to the container's loopback interface, so the user must set both binds to `0.0.0.0` in `config.json` for the published ports to actually be reachable. This is the symptom reported as items 2 + 3 of #3873; items 1 + 4 of that issue are already resolved on `main` (`Dockerfile` line 49 already exposes both ports, and README.md lines 218-220 already reflect that the WebUI ships in the wheel). Docs only, no code changes. Signed-off-by: voidborne-d <258577966+voidborne-d@users.noreply.github.com> --- docs/deployment.md | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/deployment.md b/docs/deployment.md index 746c35218..8a2cd89eb 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -10,6 +10,18 @@ > [!IMPORTANT] > Official Docker usage currently means building from this repository with the included `Dockerfile`. Docker Hub images under third-party namespaces are not maintained or verified by HKUDS/nanobot; do not mount API keys or bot tokens into them unless you trust the publisher. +> [!IMPORTANT] +> The gateway and WebSocket channel default to `host: "127.0.0.1"` in `config.json` (set in `nanobot/config/schema.py`). Docker `-p` port forwarding cannot reach a container's loopback interface, so for the host or LAN to reach the exposed ports you must set both binds to `0.0.0.0` in `~/.nanobot/config.json` before starting the container: +> +> ```json +> { +> "gateway": { "host": "0.0.0.0" }, +> "channels": { "websocket": { "host": "0.0.0.0" } } +> } +> ``` +> +> When `host` is `0.0.0.0`, the gateway refuses to start unless `token` or `tokenIssueSecret` is also configured on the WebSocket channel — see [`webui/README.md`](../webui/README.md) for details. + ### Docker Compose ```bash @@ -36,8 +48,20 @@ docker run -v ~/.nanobot:/home/nanobot/.nanobot --rm nanobot onboard # Edit config on host to add API keys vim ~/.nanobot/config.json -# Run gateway (connects to enabled channels, e.g. Telegram/Discord/Mochat) -docker run -v ~/.nanobot:/home/nanobot/.nanobot -p 18790:18790 nanobot gateway +# Run gateway (connects to enabled channels, e.g. Telegram/Discord/Mochat). +# Mirrors the security caps and port mappings declared in docker-compose.yml: +# - `--cap-drop ALL --cap-add SYS_ADMIN` + unconfined apparmor/seccomp are required +# when `tools.exec.sandbox: "bwrap"` is enabled (bwrap needs CAP_SYS_ADMIN for +# user namespaces). Without them, `bwrap` exits with `clone3: Operation not permitted`. +# - `-p 8765:8765` exposes the WebSocket channel / WebUI alongside the gateway health +# endpoint on 18790. +docker run \ + --cap-drop ALL --cap-add SYS_ADMIN \ + --security-opt apparmor=unconfined \ + --security-opt seccomp=unconfined \ + -v ~/.nanobot:/home/nanobot/.nanobot \ + -p 18790:18790 -p 8765:8765 \ + nanobot gateway # Or run a single command docker run -v ~/.nanobot:/home/nanobot/.nanobot --rm nanobot agent -m "Hello!"