diff --git a/deploy/compose.yml b/deploy/compose.yml index 711859c2..183e79fb 100644 --- a/deploy/compose.yml +++ b/deploy/compose.yml @@ -42,6 +42,17 @@ services: retries: 30 hub: <<: *hub + # The coder and designer run their commands under bubblewrap, which gives + # each one its own user, pid and mount namespaces with a fresh /proc. + # Docker's default seccomp profile refuses the namespaces without + # CAP_SYS_ADMIN, its AppArmor profile refuses the mount propagation, and + # its masked /proc paths refuse the fresh /proc, so the hub runs without + # those three and keeps its capabilities dropped. On Ubuntu 24.04 hosts + # the kernel must also allow it; see "Sandboxes" in docs/SELF_HOST.md. + security_opt: + - seccomp=unconfined + - apparmor=unconfined + - systempaths=unconfined ports: - "127.0.0.1:${PORT:-8000}:${PORT:-8000}" - "127.0.0.1:1455:1455" diff --git a/docs/SELF_HOST.md b/docs/SELF_HOST.md index b27f2e88..17c60b09 100644 --- a/docs/SELF_HOST.md +++ b/docs/SELF_HOST.md @@ -104,6 +104,25 @@ docker compose --env-file .env.hub --project-directory . -f deploy/compose.yml - `bun run docker:up` runs the same. +## Sandboxes + +The coder and designer run every command under bubblewrap, which needs a user +namespace with its capabilities intact, mount propagation and a fresh `/proc`. +The hub service runs with `seccomp=unconfined`, `apparmor=unconfined` and +`systempaths=unconfined` for that; its capabilities stay dropped. Ubuntu 24.04 +and later strip the capabilities from unprivileged user namespaces, so on such +a host (including the Ubuntu VM that Colima runs) also turn that restriction +off, and make it persist across reboots: + +```sh +sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 +echo kernel.apparmor_restrict_unprivileged_userns=0 | sudo tee /etc/sysctl.d/60-builder-userns.conf +``` + +Without it every designer and coder tool call fails with +`sandbox_tool_process_failed: bwrap: No permissions to create a new namespace` +or `bwrap: setting up uid map: Permission denied`. + ## Sidecars in Docker Agents run in sidecars. By default the hub starts them as processes beside