FAI Orchard — Self-Host Guide
Run the same v1.0 MCP server you'd get from npm or PyPI as a signed, multi-arch Docker image. Air-gap friendly. Supply-chain hardened. Multi-region tenancy supported.
ℹ️ TL;DR: `docker pull ghcr.io/frootai/mcp-orchard:1.0.0` and run. Image is non-root, HEALTHCHECK-wired, multi-arch, cosign-signed, with CycloneDX SBOM + SLSA L3 provenance attached.
§1 — Pull and verify
```bash docker pull ghcr.io/frootai/mcp-orchard:1.0.0
Verify the cosign keyless OIDC signature (always pin to image@digest):
cosign verify ghcr.io/frootai/mcp-orchard:1.0.0 \ --certificate-identity-regexp 'https://github.com/frootai/frootai/.github/workflows/publish-orchard-docker.yml@refs/tags/orchard-v.*-mcp$' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com
Verify the CycloneDX 1.5 SBOM attestation:
cosign verify-attestation --type cyclonedx ghcr.io/frootai/mcp-orchard:1.0.0 ```
End-to-end runbook (verifies npm + PyPI + Docker + SLSA all at once):
```bash node frootai-core/scripts/orchard/verify-supply-chain.js \ --tag orchard-v1.0.0-mcp --json ```
§2 — Run
```bash docker run --rm \ -p 3000:3000 \ -e FROOTAI_REGION=us-east \ -e LOG_LEVEL=info \ ghcr.io/frootai/mcp-orchard:1.0.0 ```
| Setting | Value |
|---|---|
| Base | Alpine (multi-stage) |
| User | non-root (UID 1001) |
| Port | 3000 (`EXPOSE 3000`) |
| Healthcheck | Node built-in fetch on `/health` every 30s |
| Architectures | `linux/amd64`, `linux/arm64` |
| Image size | < 80 MiB (no `npm install` at runtime) |
§3 — Health endpoint contract
`GET /health` returns:
```json { "status": "ok", "draining": false, "in_flight": 0, "started_at": "2026-05-28T10:00:00Z", "version": "1.0.0", "region": "us-east" } ```
During graceful shutdown (`SIGTERM`), the server enters `draining: true` state and `/health` returns `503` with a `Retry-After` header so rolling deploys land cleanly. The drain window is configurable via `closeGraceful({drainMs})` in code or `FROOTAI_DRAIN_MS` env var.
§4 — Multi-region tenancy
Pin a region at startup via `FROOTAI_REGION`:
| Region | Value |
|---|---|
| US East | `us-east` (default) |
| EU West | `eu-west` |
| Asia Pacific South | `ap-south` |
Cross-region READ requires the `cross-region:read` entitlement (auto-granted to enterprise tier). Cross-region WRITE is locked to DENY even with maximal entitlements — enforced as a test invariant.
§5 — Rate-limiter backend (Redis adapter)
The default in-memory limiter is fine for single-instance deployments. For multi-instance (load-balancer behind a fleet), wire the Redis adapter:
```bash docker run --rm \ -p 3000:3000 \ -e FROOTAI_RATE_LIMITER_BACKEND=redis \ -e FROOTAI_REDIS_URL=redis://your-redis:6379 \ ghcr.io/frootai/mcp-orchard:1.0.0 ```
The adapter is generic (RESP-2 wire protocol). Tested against `ioredis`, `@upstash/redis` (with the RESP-2 shim), and an in-process RESP-2 stub for CI.
§6 — Audit-log export to customer-owned bucket
For enterprise tier, audit-log segments compact atomically and export to your S3, Azure Blob, or local FS bucket:
```bash docker run --rm \ -p 3000:3000 \ -e FROOTAI_AUDIT_BACKEND=s3 \ -e FROOTAI_AUDIT_S3_BUCKET=my-bucket \ -e FROOTAI_AUDIT_S3_REGION=us-east-1 \ -e AWS_ACCESS_KEY_ID=... \ -e AWS_SECRET_ACCESS_KEY=... \ ghcr.io/frootai/mcp-orchard:1.0.0 ```
Hive-partitioned object keys: `<bucket>/region=<R>/tenant=<T>/dt=<YYYY-MM-DD>/segment-<NNN>.jsonl`. SHA-256 manifests verify against actual file bytes — manifest spoofing is detectable.
§7 — Telemetry pipeline
Errors are sampled at `FROOTAI_TELEMETRY_SAMPLE_RATE` (default `0.1`) and shaped for the Slack webhook on the alert path. Set `DO_NOT_TRACK=1` to suppress every event (hard override).
§8 — Verify it's running
```bash curl http://localhost:3000/health ```
Should return `{ "status": "ok", ... }`.
§9 — Related docs
- Aggregate v1 changelog
- Enterprise edition (multi-region + SSO)
- Pricing tier matrix
- MCP server (13-section reference)
- STABILITY.md (semver promise): https://github.com/frootai/frootai/blob/main/STABILITY.md
- SECURITY.md (disclosure policy): https://github.com/frootai/frootai/blob/main/SECURITY.md