Docker Build and Configuration#
LangBot ships a single multi-purpose Docker image (rockchin/langbot) that powers three distinct services: the main bot, the plugin runtime, and the Box sandbox service . The image is built for linux/amd64 and linux/arm64 and published automatically on GitHub Release via CI .
Dockerfile Structure#
The Dockerfile uses three build stages to keep the final image lean:
node:22-alpine AS node— builds the web UI (npm install && npx vite build)python:3.12.7-slim AS nsjail-build— compiles nsjail v3.6 from source; only the binary and its runtime libs (libprotobuf32,libnl-route-3-200) are carried into the final stage, keeping the compile toolchain (bison,flex,protobuf-dev) out of the final image- Final
python:3.12.7-slim— copies the built web dist and nsjail binary, then installs:- Docker CLI (client only) for the optional Box Docker backend
- Node.js LTS so
npx-launched MCP servers are available inside the nsjail sandbox chroot - Python dependencies via
uv sync - A
/.dockerenvsentinel file to signal container context
The default entrypoint is uv run --no-sync main.py .
CI: GitHub Actions Build#
The build-docker-image workflow triggers on release: published. It uses docker buildx for multi-arch builds:
- Stable release: tags
rockchin/langbot:<version>androckchin/langbot:latest - Pre-release: tags version only —
latestis not updated
docker-compose Services#
The docker-compose.yaml defines three services, all using the same rockchin/langbot:latest image:
| Service | Port(s) | Command | Notes |
|---|---|---|---|
langbot | 5300 (web/webhook), 2280–2285 (platform) | main.py | Main bot process |
langbot_plugin_runtime | 5401 | cli.__init__ rt | Plugin runtime |
langbot_box | — | cli.__init__ box | Optional; requires --profile box or --profile all |
langbot_box mounts /var/run/docker.sock to drive the host Docker socket and create sibling sandbox containers . The Box root path is configured via LANGBOT_BOX_ROOT (default: ${PWD}/data/box); the host and container paths must be identical because sibling containers are created with matching bind mounts .
Key env-override convention for langbot: BOX__<SECTION>__<KEY> maps to box.<section>.<key> in config.yaml and is forwarded to the Box runtime via RPC .
Sandbox Backends#
BoxRuntime probes three backends at startup in priority order: Docker → nsjail → E2B. The active backend is selected by box.backend in config.yaml (values: local, docker, nsjail, e2b); if unset, the first available local backend is used .
- Docker (
DockerBackend): wraps the Docker CLI. Creates containers labeledlangbot.box=true, enforces--cpus,--memory,--pids-limit, and--read-onlyrootfs with a tmpfs/tmp. CPU limiting can be disabled viaBOX__DOCKER__CPU_LIMIT_ENABLED=false. - nsjail (
NsjailBackend,name="nsjail"): uses the nsjail binary embedded in the image — no Docker socket required. Sessions persist state via host-directory bind mounts; uses cgroup v2 resource limits with rlimit fallback. - E2B (
E2BSandboxBackend): cloud (E2B) or self-hosted (CubeSandbox) backend. Requires thee2bPython package andE2B_API_KEY. Since there are no real bind mounts, the runtime syncs host files in/out before and after each execution ./workspaceis transparently remapped to/home/user/workspace.
BoxSpec and Custom Sandbox Images#
BoxSpec is the Pydantic model that controls every sandbox execution. Key fields:
| Field | Default | Description |
|---|---|---|
image | rockchin/langbot-sandbox:latest | Docker image (or E2B template ID) |
network | off | off or on |
timeout_sec | 30 | Execution timeout |
cpus / memory_mb / pids_limit | 1.0 / 512 / 128 | Resource limits |
read_only_rootfs | True | Read-only root filesystem |
host_path / mount_path | None / /workspace | Workspace bind mount |
extra_mounts | [] | Additional BoxMountSpec bind mounts |
persistent | False | Keep container alive across executions |
The default sandbox image is rockchin/langbot-sandbox:latest. To use a custom sandbox image, set image to any Docker image name in BoxSpec. For E2B, image is interpreted as the E2B template ID unless overridden by the e2b.template config option .
BoxProfile provides reusable preset configurations. Built-in profiles: default, offline_readonly, network_basic, network_extended. Fields listed in locked cannot be overridden by tool-call parameters .