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 (CLI runtime)` \ -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,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, and the Docker CLI. Reach for it when your keepers 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. See
The Dev Box flavor for the full breakdown.
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 the SDK runtime 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 keeper agents. Provide one:
CLAUDE_CODE_OAUTH_TOKEN— Claude Max plan auth for the CLI runtime.ANTHROPIC_API_KEY— API-pricing auth for the SDK runtime.
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, keeper agents, chats, and the sweeper fit together.
- Environment variables — the complete
PADDOCK_*reference. - Architecture — what’s happening under the hood.