Starforge — Overview & Build Flow¶
Starforge is a BuildService port inside Starbase Worker, not a separate binary. It abstracts build execution so the build backend can be swapped without changing core logic.
§16.1 Decision Rationale¶
Starform does not run its own build infrastructure at launch. Running a multi-tenant BuildKit fleet with rootless isolation, cache tuning, and incident response is 3–4 months of upfront engineering plus ~10–20% of one engineer's ongoing time — a cost that pre-seed capital is better deployed elsewhere (egress differentiation, Layers, observability, billing). Builds are also the most visible reliability surface of a PaaS: every customer sees every build, and early rough edges damage trust disproportionately.
Starforge's MVP adapter uses Depot SaaS — a remote BuildKit service with a programmatic API designed for "build on behalf of customers" use cases. Fly.io, Hathora, and other platforms run on this pattern. Depot handles the compute, cache, and infrastructure; Starform handles the integration and the customer experience layered on top.
The BuildService port abstraction keeps this swappable. When Depot spend exceeds ~$3–5k/month, or
when a specific unmet requirement emerges (non-US data residency, custom frontends, GPU builds), a
second adapter (adapter/buildkit/) can be added without touching core logic.
§16.2 MVP Flow¶
flowchart TB
classDef built fill:#3434DC22,stroke:#3434DC,color:#5B5EE8;
classDef third fill:transparent,stroke:#808080,color:#808080;
classDef store stroke-dasharray:4 3,stroke:#808080;
PUSH["Git push<br/>GitHub webhook"]:::third
API["Starbase API<br/>enqueue build job"]:::built
PICK["Starbase Worker<br/>picks up job · clones source · inspects repo"]:::built
DECIDE{"Dockerfile at<br/>repo root?"}
RAILPACK["Railpack library<br/>detects framework · generates LLB"]:::built
SUBMIT["Starforge adapter → Depot API<br/>per-workspace project"]:::built
DPATH["Dockerfile path<br/>BuildService.CreateBuild · Dockerfile frontend"]:::built
RPATH["Railpack path<br/>BuildKitService · raw LLB submission"]:::built
DEPOT["Depot<br/>ephemeral BuildKit · workspace-scoped cache"]:::third
REG[("DO Container Registry")]:::store
LOGS["Worker relays live build logs to Stardeck<br/>+ archives one object per build → DO Spaces"]:::built
POLL["Worker polls build status → Postgres<br/>on success: update desired state w/ new image SHA"]:::built
TICK["Next Shuttle tick<br/>picks up new image · deploys"]:::third
PUSH --> API --> PICK --> DECIDE
DECIDE -- "yes" --> SUBMIT
DECIDE -- "no" --> RAILPACK --> SUBMIT
SUBMIT --> DPATH
SUBMIT --> RPATH
DPATH --> DEPOT
RPATH --> DEPOT
DEPOT --> REG
DEPOT --> LOGS --> POLL --> TICK
Dockerfile goes straight to BuildService.CreateBuild; otherwise Railpack detects the framework and emits LLB submitted via BuildKitService. Both share one per-workspace Depot project, push to the registry, relay build logs live (archived to DO Spaces, §16.6), and end at a Shuttle tick. Brand-blue boxes are Starform-built; gray are third-party; dashed is a data store.Push targeting (per-region registries): registries are one per region (DO
multi-registry, regionally placed for in-region pull locality). The Worker resolves the service's
placement region(s) (FR-077) via that
region's RegistryProvider (§10) and Depot pushes the image to each
such registry — usually exactly one; a service deployed in two regions gets its image pushed to
both. At single-region MVP this is indistinguishable from a single registry.
Image-source services skip the build
A service with source_type: image (schema) has no
repo to clone or build — its image_ref flows straight into the desired-state image
(§25.1) and Depot is never involved. This is the
substrate for image-based one-click templates (§39.3); the git flow above is unchanged.
Cross-references
The BuildService port contract → §16.3 · the
Dockerfile-vs-Railpack frontend strategy → §16.5 ·
build log streaming (live + DO Spaces archive) → §16.6 · the Git push +
webhook entry point → §16.11 · the build state machine →
§16.12 · the Worker binary that runs this →
Starbase §14 · the desired state a finished build
updates → Starbase §32.