Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

Self-hosting

The local path is Docker Compose. The image is the same one you run elsewhere.

From v2/:

Terminal window
docker compose -f deploy/compose/compose.yaml build keys
docker compose -f deploy/compose/compose.yaml up -d
Port Process
127.0.0.1:18000 Reactor. Console at /console. Health at /health
127.0.0.1:18001 A second Reactor process, same database and bucket
127.0.0.1:5440 Shared Postgres
127.0.0.1:5441 Dedicated-database Postgres
127.0.0.1:19000 S3-compatible blob store

The keys service writes the JWT private key and exits. Both app containers mount that volume read-only. Function workdirs are separate volumes, so a zip unpacked on one replica is not assumed to exist on the other. The blob store is the source of truth. Invoke unpacks again when the local copy is missing.

base_domain is apps.localhost. A project site is http://{ref}.apps.localhost:18000/.

First-run setup is the console or reactor setup. Then create a project.

v2/deploy/fly/fly.toml runs the same image in listen mode. place is fly, so the console shows that. PostgREST is on 127.0.0.1:3000 inside the machine. Blobs are S3-compatible storage, not the machine disk. The health check is GET /health.

Secrets (database URL, operator token, storage keys, JWT) stay in the Fly secret store. They are not in the toml file that is committed.

Add replicas when CPU is the limit. They share Postgres and the blob bucket. Nothing in the client URL changes. Add a dedicated database when one project is the limit, by setting that project’s database_url. Callers still use the same host and the same keys.

The AWS layout is the Lambda page.