Self-hosting
The platform runs in three shapes, and the same workspace moves between them unchanged. Pick by who the install is for.
| shape | for | isolation |
|---|---|---|
| a laptop | one person, no server — the CLI alone | the process |
| one box | a team; docker compose |
one hardened container per step |
| a cluster | a company, or anyone else’s agents | one gVisor pod per step |
One box
git clone https://github.com/foldrun-io/foldrun-infra
cp env.example .env # set FOLDRUN_SECRET_KEY and a model credential
docker compose up -d --build
That is the whole platform in one container: the dashboard, the worker, and the runner image every step executes in. Everything it knows is files on the data volume; back that up. The rest of this page is what to set once it is up.
The one variable that is a security boundary
FOLDRUN_RUN_ISOLATION says where a step’s code executes:
container— one hardened container per step, on the box. The default fordocker compose.k8s— one pod per step, under gVisor when the cluster has it.- unset — in the platform’s own process. Fine on a laptop, catastrophic
for anyone else’s agents: a step would hold the platform’s filesystem,
its vault and every other account’s data. The platform refuses to start in
that shape once a second account exists, or when
FOLDRUN_MULTI_TENANT=1says one is coming.
See Security for what the sandbox does and does not allow.
Data
Files first, and the rule for what leaves them is markdown for what people author, a database for what the system accumulates:
- files — every workspace, run record, user and key, on the data volume. The folder model is the product; do not try to move it into a database. With nothing else configured, this is the whole store, and it is what a single box runs on.
- Postgres (
FOLDRUN_DATABASE_URL, optional) — sessions, the audit log, the ledger, the run queue. Set it when more than one worker, or real money, is involved; unset it and the file paths are still there. - Redis (
FOLDRUN_REDIS_URL, optional) — rate limits, worker leases, caches: only what can be rebuilt, so a restart costs a cold cache. - the file store — workspace storage blobs: local disk, or any
S3-compatible bucket (
FOLDRUN_STORAGE_DRIVER=s3with theFOLDRUN_S3_*variables). Run pods reach it only through presigned URLs. - search (
FOLDRUN_SEARCH_URL, optional) — a SearXNG instance thewebsearchtool queries, so a search leaves the box as a query and not as a vendor API call.
A public address
FOLDRUN_PUBLIC_URL is the origin the outside world reaches the install on.
Without it, approval links are left out of notifications and share links
cannot be minted. Put TLS in front — a reverse proxy, a tunnel, a load
balancer — and set FOLDRUN_TRUST_PROXY=1, or the login rate limiter
cannot tell callers apart and limits nothing. It is one variable and it is
easy to forget precisely because nothing visibly breaks without it.
Letting people in
FOLDRUN_OPEN_SIGNUP=1 lets strangers create accounts. It should be the
last switch turned on, after isolation, a public address, billing if you
charge, and FOLDRUN_MULTI_TENANT=1. A fresh install with no users answers
/signup for its first account regardless.
Models
A model credential at the platform (ANTHROPIC_API_KEY or a Claude OAuth
token) is the default every account uses. Accounts and workspaces can bring
their own — see Providers — and a fallback endpoint
(FOLDRUN_FALLBACK_*) carries a step whose primary refuses.
Backups
Nightly: the data volume as a tarball, and the platform’s own configuration
sealed with age to a public key the box holds and cannot open — so a
stolen backup carries the wrapped account keys and not the root key that
wraps them. Ship both somewhere off the box. Then perform a restore into a
scratch directory, once, before you need to: a backup nobody has opened is a
rumour.
Observability
Every step records its startup time, compute seconds, peak memory and
network bytes. /api/metrics exposes the platform’s counters for a scraper
holding FOLDRUN_METRICS_TOKEN; the reference install ships dashboards and
alert rules for Grafana. Queue depth and the age of the oldest pending run
are the two numbers that say whether the install is keeping up.
A cluster
The k8s/ directory in foldrun-infra is the manifest: the platform, the
datastores, a gVisor RuntimeClass, and the NetworkPolicy that keeps run
pods off private networks and the cloud metadata endpoint. Concurrency is
hardware — each run pod reserves the memory a step declares (size:) — so
the number of parallel steps a node carries is its RAM divided by that. The
runner image is large; bake it into node images where nodes appear on their
own.