Docker (optional)
Docker is optional. Use it only if you want a containerized gateway or to validate the Docker flow.Is Docker right for me?
- Yes: you want an isolated, throwaway gateway environment or to run Pllan on a host without local installs.
- No: you are running on your own machine and just want the fastest dev loop. Use the normal install flow instead.
- Sandboxing note: agent sandboxing uses Docker too, but it does not require the full gateway to run in Docker. See Sandboxing.
Prerequisites
- Docker Desktop (or Docker Engine) + Docker Compose v2
- At least 2 GB RAM for image build (
pnpm installmay be OOM-killed on 1 GB hosts with exit 137) - Enough disk for images and logs
- If running on a VPS/public host, review
Security hardening for network exposure,
especially Docker
DOCKER-USERfirewall policy.
Containerized Gateway
Build the image
From the repo root, run the setup script:This builds the gateway image locally. To use a pre-built image instead:Pre-built images are published at the
GitHub Container Registry.
Common tags:
main, latest, <version> (e.g. 2026.2.26).Complete onboarding
The setup script runs onboarding automatically. It will:
- prompt for provider API keys
- generate a gateway token and write it to
.env - start the gateway via Docker Compose
Open the Control UI
Open
http://127.0.0.1:18789/ in your browser and paste the token into
Settings.Need the URL again?Manual flow
If you prefer to run each step yourself instead of using the setup script:Run
docker compose from the repo root. If you enabled PLLAN_EXTRA_MOUNTS
or PLLAN_HOME_VOLUME, the setup script writes docker-compose.extra.yml;
include it with -f docker-compose.yml -f docker-compose.extra.yml.Environment variables
The setup script accepts these optional environment variables:| Variable | Purpose |
|---|---|
PLLAN_IMAGE | Use a remote image instead of building locally |
PLLAN_DOCKER_APT_PACKAGES | Install extra apt packages during build (space-separated) |
PLLAN_EXTENSIONS | Pre-install extension deps at build time (space-separated names) |
PLLAN_EXTRA_MOUNTS | Extra host bind mounts (comma-separated source:target[:opts]) |
PLLAN_HOME_VOLUME | Persist /home/node in a named Docker volume |
PLLAN_SANDBOX | Opt in to sandbox bootstrap (1, true, yes, on) |
PLLAN_DOCKER_SOCKET | Override Docker socket path |
Health checks
Container probe endpoints (no auth required):HEALTHCHECK that pings /healthz.
If checks keep failing, Docker marks the container as unhealthy and
orchestration systems can restart or replace it.
Authenticated deep health snapshot:
LAN vs loopback
scripts/docker/setup.sh defaults PLLAN_GATEWAY_BIND=lan so host access to
http://127.0.0.1:18789 works with Docker port publishing.
lan(default): host browser and host CLI can reach the published gateway port.loopback: only processes inside the container network namespace can reach the gateway directly.
Use bind mode values in
gateway.bind (lan / loopback / custom /
tailnet / auto), not host aliases like 0.0.0.0 or 127.0.0.1.Storage and persistence
Docker Compose bind-mountsPLLAN_CONFIG_DIR to /home/node/.pllan and
PLLAN_WORKSPACE_DIR to /home/node/.pllan/workspace, so those paths
survive container replacement.
For full persistence details on VM deployments, see
Docker VM Runtime - What persists where.
Disk growth hotspots: watch media/, session JSONL files, cron/runs/*.jsonl,
and rolling file logs under /tmp/pllan/.
Shell helpers (optional)
For easier day-to-day Docker management, installClawDock:
clawdock-start, clawdock-stop, clawdock-dashboard, etc. Run
clawdock-help for all commands.
See the ClawDock Helper README.
Enable agent sandbox for Docker gateway
Enable agent sandbox for Docker gateway
docker.sock only after sandbox prerequisites pass. If
sandbox setup cannot complete, the script resets agents.defaults.sandbox.mode
to off.Automation / CI (non-interactive)
Automation / CI (non-interactive)
Disable Compose pseudo-TTY allocation with
-T:Shared-network security note
Shared-network security note
Permissions and EACCES
Permissions and EACCES
The image runs as
node (uid 1000). If you see permission errors on
/home/node/.pllan, make sure your host bind mounts are owned by uid 1000:Faster rebuilds
Faster rebuilds
Order your Dockerfile so dependency layers are cached. This avoids re-running
pnpm install unless lockfiles change:Power-user container options
Power-user container options
The default image is security-first and runs as non-root
node. For a more
full-featured container:- Persist
/home/node:export PLLAN_HOME_VOLUME="pllan_home" - Bake system deps:
export PLLAN_DOCKER_APT_PACKAGES="git curl jq" - Install Playwright browsers:
- Persist browser downloads: set
PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwrightand usePLLAN_HOME_VOLUMEorPLLAN_EXTRA_MOUNTS.
OpenAI Codex OAuth (headless Docker)
OpenAI Codex OAuth (headless Docker)
If you pick OpenAI Codex OAuth in the wizard, it opens a browser URL. In
Docker or headless setups, copy the full redirect URL you land on and paste
it back into the wizard to finish auth.
Base image metadata
Base image metadata
The main Docker image uses
node:24-bookworm and publishes OCI base-image
annotations including org.opencontainers.image.base.name,
org.opencontainers.image.source, and others. See
OCI image annotations.Running on a VPS?
See Hetzner (Docker VPS) and Docker VM Runtime for shared VM deployment steps including binary baking, persistence, and updates.Agent Sandbox
Whenagents.defaults.sandbox is enabled, the gateway runs agent tool execution
(shell, file read/write, etc.) inside isolated Docker containers while the
gateway itself stays on the host. This gives you a hard wall around untrusted or
multi-tenant agent sessions without containerizing the entire gateway.
Sandbox scope can be per-agent (default), per-session, or shared. Each scope
gets its own workspace mounted at /workspace. You can also configure
allow/deny tool policies, network isolation, resource limits, and browser
containers.
For full configuration, images, security notes, and multi-agent profiles, see:
- Sandboxing — complete sandbox reference
- OpenShell — interactive shell access to sandbox containers
- Multi-Agent Sandbox and Tools — per-agent overrides
Quick enable
Troubleshooting
Image missing or sandbox container not starting
Image missing or sandbox container not starting
Build the sandbox image with
scripts/sandbox-setup.sh
or set agents.defaults.sandbox.docker.image to your custom image.
Containers are auto-created per session on demand.Permission errors in sandbox
Permission errors in sandbox
Set
docker.user to a UID:GID that matches your mounted workspace ownership,
or chown the workspace folder.Custom tools not found in sandbox
Custom tools not found in sandbox
Pllan runs commands with
sh -lc (login shell), which sources
/etc/profile and may reset PATH. Set docker.env.PATH to prepend your
custom tool paths, or add a script under /etc/profile.d/ in your Dockerfile.OOM-killed during image build (exit 137)
OOM-killed during image build (exit 137)
The VM needs at least 2 GB RAM. Use a larger machine class and retry.
Unauthorized or pairing required in Control UI
Unauthorized or pairing required in Control UI
Gateway target shows ws://172.x.x.x or pairing errors from Docker CLI
Gateway target shows ws://172.x.x.x or pairing errors from Docker CLI
Reset gateway mode and bind: