Self-hosting
Run the whole platform yourself with Docker Compose — the same MIT-licensed product as Peractor Cloud.
Peractor is one MIT-licensed product with two supported ways to run it: Peractor Cloud (we operate it) and self-hosted (you do). Self-hosting is not a reduced edition — same workflows, gates, connectors, and apps. The officially supported deployment is a single-node Docker Compose stack.
What you need
- Docker. Postgres ships as a service in the compose file, and every run executes in a sandbox container the host launches — isolation is mandatory, so the sandbox image must exist.
- An agent credential. Runs execute inside containers, which
can't see an interactive
claudelogin on the machine. Use a subscription token fromclaude setup-token(CLAUDE_CODE_OAUTH_TOKEN) or anANTHROPIC_API_KEY; addOPENAI_API_KEYif your workflows select Codex. - A git push credential for runs that push branches and open pull requests: a GitHub App, or a token/SSH key connected in the app — see Git & credentials.
Quick start
# 1. Get the source and build the sandbox image (mandatory)
git clone https://github.com/peractor-ai/peractor && cd peractor
docker build -f infra/docker/Dockerfile --target sandbox -t peractor-sandbox .
# 2. Configure — at minimum: POSTGRES_PASSWORD, PERACTOR_SECRET_KEY,
# and an agent credential such as CLAUDE_CODE_OAUTH_TOKEN
cp infra/docker/.env.example infra/docker/.env
# 3. Up
docker compose -f infra/docker/compose.saas.yaml \
--env-file infra/docker/.env up --build
Open http://localhost:7878, sign up — the first account
is yours — and create your organization. A fresh host works out of the
box: a built-in default workflow, console notifications, no connectors
required.
Point your editor at it
Repositories choose their control plane with
peractorrc.json at the repo root — the only file Peractor ever
keeps in a repo:
{ "host": "https://peractor.internal.example.com", "project": "…" }
Without a host entry the apps use Peractor Cloud. The
extension fills this file in when you
connect the repo to a project.
Hardening
- Every run container is one-shot and locked down: non-root, all
capabilities dropped, no privilege escalation, CPU/memory/pid caps
(
PERACTOR_RUN_CPU,PERACTOR_RUN_MEM_MB,PERACTOR_RUN_PIDS). - Set
PERACTOR_ISOLATION=gvisoronce the Docker daemon has the gVisorrunscruntime for a kernel-level boundary — recommended when people you don't fully trust can start runs. PERACTOR_SECRET_KEYencrypts every per-org secret at rest. Keep it stable and backed up — rotating it makes existing secrets undecryptable.- The host mounts the Docker socket to launch run containers: treat the host as your trust boundary and give it an isolated daemon.
- Cap load with
PERACTOR_MAX_CONCURRENT_RUNSandPERACTOR_MONTHLY_RUN_QUOTA.
Useful knobs
| Variable | |
|---|---|
PERACTOR_DB | Postgres connection string (required). |
PERACTOR_PUBLIC_URL | Public origin — OAuth callbacks, secure cookies, links in email. |
PERACTOR_ISOLATION | container (default) or gvisor. |
PERACTOR_RESEND_API_KEY, PERACTOR_EMAIL_FROM | Email delivery for invites; without them, links are copy-paste. |
PERACTOR_GITHUB_OAUTH_CLIENT_ID/_SECRET | "Continue with GitHub" (same pattern for Google and Linear). |
PERACTOR_APNS_*, PERACTOR_FCM_* | Mobile push, each platform independent. |
PERACTOR_POLL_MS | Tracker poll interval (default 30000). |
Every knob — sign-in providers, tracker and notifier OAuth apps, push,
quotas — is documented in .env.example, and every optional
group degrades gracefully when unset.
Local repositories. Unlike Cloud, a self-hosted control plane may bind a project to a local filesystem path — handy for trying Peractor against a repo on the same box before wiring up a git remote.
To run phases on other machines you own, register remote runners — see Runners & isolation.