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 claude login on the machine. Use a subscription token from claude setup-token (CLAUDE_CODE_OAUTH_TOKEN) or an ANTHROPIC_API_KEY; add OPENAI_API_KEY if 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=gvisor once the Docker daemon has the gVisor runsc runtime for a kernel-level boundary — recommended when people you don't fully trust can start runs.
  • PERACTOR_SECRET_KEY encrypts 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_RUNS and PERACTOR_MONTHLY_RUN_QUOTA.

Useful knobs

Variable
PERACTOR_DBPostgres connection string (required).
PERACTOR_PUBLIC_URLPublic origin — OAuth callbacks, secure cookies, links in email.
PERACTOR_ISOLATIONcontainer (default) or gvisor.
PERACTOR_RESEND_API_KEY, PERACTOR_EMAIL_FROMEmail 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_MSTracker 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.