Skip to main content
The server interface is in private early access. Contact bryan@qlty.sh if you’re interested in trying it.
The supported deployment artifact is the official Fabro image at ghcr.io/fabro-sh/fabro. Everything else — docker compose, ECS, Cloud Run, Kubernetes, Railway — is just running this image somewhere with the right requirements.

Requirements

RequirementValue
Imageghcr.io/fabro-sh/fabro:nightly (multi-arch; pin a version for production)
Persistent volumeMount at /storage. Stores run history, checkpoints, sessions, the dev token, and JWT keys.
PortThe container binds to $PORT (default 32276). Expose it.
LLM provider keyAdd at least one provider key during the install wizard or later with fabro secret set / fabro provider login.
ReplicasOne. The server expects exclusive ownership of /storage.

Quickstart with docker compose

The repo ships a docker-compose.yaml at the root. Clone the repo (or copy the file), create a .env for bootstrap settings if needed, and start it:
git clone https://github.com/fabro-sh/fabro.git
cd fabro
cp .env.example .env
# edit .env for bootstrap values such as SESSION_SECRET or FABRO_DEV_TOKEN if needed
docker compose up -d
The compose file:
  • Pulls ghcr.io/fabro-sh/fabro:nightly
  • Creates a named volume fabro-storage mounted at /storage
  • Mounts /var/run/docker.sock so Fabro can spawn sandbox containers on the host daemon
  • Exposes port 32276
  • Loads environment from .env if present
Mounting /var/run/docker.sock gives the container host-root-equivalent access. Only use the bundled compose service in trusted, single-tenant deployments. See Sandboxing for the threat model.
After the container is healthy, finish setup in your browser following the install wizard.

Adding a reverse proxy with TLS

For a production deployment exposed to the internet, layer the docker-compose.prod.yaml overlay on top. It adds a Caddy reverse proxy that terminates TLS (auto-provisioning a Let’s Encrypt certificate) and forwards to Fabro:
# In .env
FABRO_DOMAIN=fabro.example.com

# Then bring the stack up
docker compose -f docker-compose.yaml -f docker-compose.prod.yaml up -d
Leave FABRO_DOMAIN unset to serve plain HTTP on localhost.

Bootstrap environment variables

For the web UI you need a session secret unless install mode is generating the initial local configuration:
SESSION_SECRET=<64-character hex string>
Generate one with openssl rand -hex 32. server.env and container process env are for bootstrap values only:
VariablePurpose
SESSION_SECRETSession encryption secret
FABRO_DEV_TOKENOptional — pre-set the dev token instead of reading the one written to /storage on first boot
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKENOptional static S3 object-store credentials
Do not put optional integration secrets in .env for server runtime. Configure LLM provider keys, Slack, Daytona, Brave Search, GITHUB_TOKEN, and GitHub App secrets in the vault with fabro secret set, fabro provider login, or fabro install. Optional:
VariablePurpose
FABRO_DOMAINPublic hostname when using the Caddy reverse-proxy overlay
See Server Configuration for the full settings reference, and .env.example for the complete list.

Cloud container services

The same image works on any container orchestrator that supports the requirements above. Common patterns:
  • AWS ECS / Fargate — Task definition referencing ghcr.io/fabro-sh/fabro:nightly, EFS volume mounted at /storage, port 32276 published, environment variables for bootstrap values, and vault-backed optional integration secrets.
  • Google Cloud Run — Cloud Run with a backed volume mount at /storage. Pin minimum instances to 1; scale-to-zero interrupts running workflows.
  • Kubernetes — One-replica StatefulSet (not Deployment) with a PersistentVolumeClaim mounted at /storage. Expose via Service + Ingress.
In all cases: single replica, persistent /storage, expose $PORT, and configure optional integration secrets in the vault.

Pinning a version

docker-compose.yaml uses :nightly by default, so docker compose pull && docker compose up -d picks up the latest nightly. To pin a specific version, change the image: line to ghcr.io/fabro-sh/fabro:<version>. Release artifacts ship with SLSA Build Provenance attestations you can verify with gh attestation verify.

Pointing the CLI at your server

Once the container is running, install the CLI on your local machine and point it at the server:
~/.fabro/settings.toml
[cli.target]
type = "http"
url = "https://fabro.example.com/api/v1"
For dev-token auth, save the token in the CLI auth store:
fabro auth login --server https://fabro.example.com/api/v1 --dev-token fabro_dev_...
See Server Operations for the full CLI-target options.

Caveats

  • Volume is load-bearing. Without a persistent volume at /storage, redeploys silently wipe all state — including the dev token and JWT signing keys.
  • Single replica. The server expects exclusive ownership of /storage. Don’t scale to multiple replicas.
  • Architecture. The :nightly tag is multi-arch. The amd64 variant is the most heavily tested.

Next steps

Server Operations

Install wizard, web UI, authentication, demo mode, and pointing the CLI at the server.

Server Configuration

Full settings.toml reference — auth, reverse-proxy TLS, run defaults, and more.

Deploy to Railway

One-click managed shortcut for the same Docker image.

Sandboxing

The Docker sandbox provider’s security model and trust assumptions.