Getting started
Paddock is a single process per data root + port. The fastest way to try it is the published Docker image; you can also run it from source for development.
Run with Docker
Section titled “Run with Docker”Run the published image, point it at a data volume, and give it a Claude token:
docker run -d --name paddock -p 127.0.0.1:4000:4000 \ -e CLAUDE_CODE_OAUTH_TOKEN=… `# Max plan auth (or ANTHROPIC_API_KEY)` \ -e PADDOCK_DATA_DIR=/data \ -e PADDOCK_DANGEROUSLY_ALLOW_OPEN=1 `# required in a container — see below` \ -v paddock-data:/data \ ghcr.io/edspencer/paddock:latestThen open http://localhost:4000 and click New Project.
Two image flavors: base vs devbox
Section titled “Two image flavors: base vs devbox”Paddock publishes two official images from the same source — pick the tag that matches what your agents do:
ghcr.io/edspencer/paddock:latest— the base image (used above). The lean runtime: the Paddock app plusgit,openssh-client,gh, and theclaudeCLI. Everything a stock instance needs to read, write, and reason over code.ghcr.io/edspencer/paddock:devbox— the devbox image. Base plus the coding-agent toolbox:pm/PM2 preview servers,ffmpeg, a headless Playwright MCP browser, the Docker CLI (with thebuildxandcomposeplugins),kubectl, and a scripting kit (python3,uv,jq,rsync). Reach for it when Claude needs to build and run apps, not just edit them.
The devbox only adds tools — same app, same /data layout — so you can swap tags
against the same volume. It’s a much bigger image (the Chromium layer alone is ~1 GB),
so stay on base unless you need those tools.
The Dev Box flavor is the canonical breakdown of what each
image carries, and why each tool is in the image it’s in.
docker-compose
Section titled “docker-compose”services: paddock: image: ghcr.io/edspencer/paddock:latest ports: # Loopback only. Do NOT use "4000:4000" without an auth mode in front. - "127.0.0.1:4000:4000" environment: CLAUDE_CODE_OAUTH_TOKEN: ${CLAUDE_CODE_OAUTH_TOKEN} # or ANTHROPIC_API_KEY for API pricing PADDOCK_DATA_DIR: /data # Required in a container — see the caution above. PADDOCK_DANGEROUSLY_ALLOW_OPEN: "1" volumes: - paddock-data:/datavolumes: paddock-data:Claude authentication
Section titled “Claude authentication”Paddock passes your Claude credentials through to the agents. Provide one:
CLAUDE_CODE_OAUTH_TOKEN— Claude Max plan auth.ANTHROPIC_API_KEY— API-pricing auth.
Either works on either runtime — the choice of credential is independent of how a turn is driven.
The token is passed through the process environment; it is never written to disk by Paddock.
Run from source
Section titled “Run from source”You need Node 22+ and the claude CLI on your PATH.
git clone https://github.com/edspencer/paddock.gitcd paddocknpm installProduction-like (one process serves API + WS + SPA)
Section titled “Production-like (one process serves API + WS + SPA)”This is how the deployed service runs — the server serves the built SPA and exposes
/api + /ws on the same origin.
# Load your Claude token into the environment (never echo it).export CLAUDE_CODE_OAUTH_TOKEN=…
npm run build # build web dist + server distexport PADDOCK_DATA_DIR="$(mktemp -d /tmp/paddock-dev.XXXXXX)" # optional throwaway data dirnpm run start # node packages/server/dist/index.jsOpen http://localhost:4000/. Quick checks:
curl -s http://localhost:4000/api/health # {"ok":true}curl -s http://localhost:4000/api/projects # {"projects":[...]}Hot-reload dev (two processes)
Section titled “Hot-reload dev (two processes)”For frontend iteration — Vite serves the SPA on :5173 and proxies /api + /ws
to the backend on :4000:
npm run dev # terminal 1 — backend (watched) on :4000npm run dev:web # terminal 2 — Vite SPA on :5173See the repo’s DEV.md for the full local-development guide.
Next steps
Section titled “Next steps”- Concepts — how projects, agents, chats, and the sweeper fit together.
- Environment variables — the complete
PADDOCK_*reference. - Architecture — what’s happening under the hood.