Infrastructure-as-code for the FoldForge MVP.
- Terraform (
terraform/) provisions Hetzner Cloud (network, firewall, app node, Postgres data volume) and Cloudflare R2 (artifact + MSA-cache buckets). - Docker Compose (
compose/) defines the runtime stack that runs on the app node:postgres,orchestrator,gateway, andcaddy(auto-HTTPS). - Scripts (
scripts/) bootstrap remote state and deploy the stack.
Internet
│ 443
┌─────▼─────┐
│ caddy │ (auto TLS)
└─────┬─────┘
┌─────▼─────┐ gRPC ┌──────────────┐
│ gateway │─────────▶│ orchestrator │
└───────────┘ └──────┬───────┘
gRPC │ │ sqlx
┌───────────────▼─┐ ┌─▼──────────┐
│ GPU sidecars* │ │ postgres │
│ rfdiff/mpnn/... │ │ (volume) │
└──────────────────┘ └────────────┘
*rented GPU hosts, wired later
Cloudflare R2: artifact blobs + AF2 MSA cache
cd terraform
cp terraform.tfvars.example terraform.tfvars # fill tokens + SSH keys
cp backend.hcl.example backend.hcl # R2 state creds
../scripts/bootstrap-state.sh # one-time: create state bucket
terraform init -backend-config=backend.hcl
terraform plan
terraform apply# on the app node (ssh in), from a checkout of this repo:
cp compose/.env.example compose/.env # fill secrets + image tags
./scripts/deploy.shdeploy.sh pulls pinned images, brings the stack up, and waits on
/v1/healthz. Image tags are pinned in compose/.env (GATEWAY_TAG,
ORCHESTRATOR_TAG) — bump them to roll forward.
- An optional distributed-tracing overlay lives at
compose/docker-compose.trace.yml(an OpenTelemetry collector + Jaeger all-in-one). The services already propagate a W3Ctraceparentend to end (#M5); this overlay is the export sink. SeeTRACE-DEPLOY.mdfor the runbook (it's gated on the per-service OTLP exporter, which is deferred). - GPU sidecars are not provisioned by Terraform in the MVP; rent GPU hosts
separately and set
SIDECAR_*endpoints incompose/.env. - Postgres runs as a container on a Hetzner volume for the MVP. Swap for a managed DB by replacing the volume + compose service when scale demands it.
MIT