Development setup
Bring SpipCP up on your own machine — dev services, the database, the panel and worker — plus the 34xx port convention, the green gate, the rig, and how to run this docs site.
This is the contributor setup: how to run the whole stack locally so you can build against it. For the operator install (Docker on a server) see Installation; for a click-through of the product see Getting started.
Prerequisites
| Tool | Version | For |
|---|---|---|
| Node | 24+ | The panel, worker, and this docs site. |
| pnpm | 11.5.3+ | The monorepo package manager (packageManager is pinned). |
| Docker | recent | The dev services (Postgres, Garage S3, Pebble, Gitea, mailpit). |
| A VM tool | — | OrbStack (orb) or Multipass, to stand in for a managed server. |
| Go | recent | Only if you're touching the fleet agent (agent/). |
Start the stack
From the repo root:
docker compose -f docker-compose.dev.yml up -d # Postgres, Garage S3, Pebble, Gitea, mailpit
pnpm install # workspace deps
pnpm db:reset # migrate + seed roles (clean slate)
pnpm dev:all # panel :3400 + worker :3401 togetherOpen http://localhost:3400 and sign up — the first account becomes a pre-verified admin. Then walk the dashboard's Get started checklist. Useful variants:
pnpm dev— panel only (no worker).pnpm dev:worker— worker only.pnpm db:reset:seed— reset and seed demo data.
Postgres is the only stateful service
No Redis, no separate broker. Jobs, state, and audit all live in Postgres (the dev DB is the
compose db service on host port 3432). The job queue is a table, so it survives a restart.
The 34xx port convention
Everything dev-facing lives in the 34xx range so ports never collide:
| Port | Service |
|---|---|
| 3400 | Panel (web) |
| 3401 | Worker (job queue + agent gateway) |
| 3402 | This docs site |
| 3408 | Dev edge Caddy (tunnel profile) |
| 3410 | Garage (dev S3 API — the throwaway fixture the rig backs up to) |
| 3412 / 3413 | Pebble (ACME / management) |
| 3414 / 3415 | Gitea (HTTP / SSH) |
| 3416 / 3417 | mailpit (SMTP / web UI) |
| 3432 | Postgres (dev) |
The panel and worker (and this docs site) run natively via pnpm; the services above run in
Docker via docker-compose.dev.yml.
Run this docs site
The docs are a standalone Fumadocs app — not wired into the panel or the prod proxy. Run it directly:
pnpm --filter @spipcp/docs dev # → http://localhost:3402/ redirects to /docs; pages live under content/docs/*.mdx and are ordered in
content/docs/meta.json. There is no hosted URL today — it's local-only.
Regenerating the screenshots
The images under spipcp-docs/public/img/ are captured from the real panel UI against a seeded
demo estate (no live worker needed). When a screen changes, regenerate them:
DOCS_SCREENS=1 pnpm --filter panel e2e docs-screenshots.spec.ts # data-driven routes
DOCS_SCREENS=1 pnpm --filter panel e2e docs-screenshots-live.spec.ts # dialogs, wizards, terminalsBoth specs seed POST /api/dev/test-support {seed:"fleet"} into the isolated <db>_test database,
log in, walk each route, and write one PNG per <Screenshot src> slot. The
Screenshot index lists every captured surface.
The green gate
Before claiming anything is done, run the repo-root check — it's the real gate, not a per-package
tsc:
pnpm check # biome + per-package checks + knip + file-line/protocol/token guards
pnpm test # unit tests across packagespnpm check is what catches drift. Run it from the root and read its tail before saying "green."
The rig
SpipCP is rig-first: provisioning features are proven by an automated harness before any UI is trusted (see Contributing for the rule behind this). Run it with:
pnpm rig # the standard harness pass
pnpm rig:hostile # the hostile-conditions variantEnd-to-end flows (a real VM + worker + panel children driven together) run via the e2e:* scripts,
e.g. pnpm e2e:flow-a.
Next steps
- Project layout — what each package in the monorepo is.
- Contributing — the workflow and the rules that don't bend.
- Getting started — drive the product end to end against a local VM.
Screenshot index
Every product screenshot in these docs, in one place — a contact sheet linking each image to the page it documents, and the one command that regenerates them all.
Project layout
A map of the monorepo — what each package is, which decide vs. act, and where the plans, runbooks, and authoritative docs live.