Ports Detail (Swappable Per Region)¶
Ports define what Starbase needs from cloud infrastructure. Each region maps to one implementation of each port. Swapping clouds means writing new adapters, not changing core logic.
| Port Interface | What It Abstracts | MVP Adapter | Future Adapters |
|---|---|---|---|
| ClusterProvider | Customer-cluster lifecycle: create, delete, scale, get status | Self-managed Talos on DO droplets (godo for droplets; MVP manual talosctl, post-MVP Shipyard) |
Talos on AWS EC2 / GCP GCE (plain VMs — the adapter targets self-managed Talos, not managed EKS/GKE, which can't expose the gVisor RuntimeClass, FR-082) |
| DatabaseProvider | Dedicated managed DB tiers (Micronova+): create, resize, backups, PITR, connection strings, and DB-side network scoping to the hosting cluster's nodes (FR-075 — DO: Trusted Sources by tag; others: security groups / IP allowlists). Mininova throwaway instances flow through desired state (Shuttle-rendered pods), not this port (Managed Databases) | DO Managed Postgres | AWS RDS, GCP Cloud SQL |
| CacheProvider | Managed cache: create, resize, connection strings | DO Managed Valkey | AWS ElastiCache, GCP Memorystore |
| RegistryProvider | Container images: create repo, push/pull credentials, list tags — one registry instance per region (the Region struct binds it, §12); builds push to the placement region's registry (§16.2) |
DO Container Registry (per region) | AWS ECR, GCP Artifact Registry |
| StorageProvider | Object storage: create isolated tenant org, provision bucket, generate per-customer credentials, revoke on offboarding | Tigris (Partner Integration API) | AWS S3, GCP GCS, Cloudflare R2 |
| DNSProvider | DNS records: create, update, delete A/CNAME records | Cloudflare | Cloudflare (unchanged across clouds) |
| PaymentProvider | Billing: create customer, create subscription, usage reporting, invoices | Stripe | Stripe (unchanged) |
| BuildService | Build execution: framework detection, submit build, poll status, get image reference, stream logs | Depot SaaS + Railpack (primary) + Dockerfile (fallback) | Self-hosted BuildKit, AWS CodeBuild |
| JobQueue | Async jobs: enqueue, dequeue, ack, retry | Postgres table (MVP) | RabbitMQ (scale) |
Wiring example in cmd/api/main.go:
Region wiring · cmd/api/main.go
regions := region.NewRegistry()
regions.Register("nyc3", region.Config{
Cloud: "digitalocean",
Cluster: digitalocean.NewClusterAdapter(doClient),
Database: digitalocean.NewDatabaseAdapter(doClient),
Cache: digitalocean.NewCacheAdapter(doClient),
Registry: digitalocean.NewRegistryAdapter(doClient),
Storage: tigris.NewStorageAdapter(tigrisClient), // Partner Integration API
})
// Core uses ports — doesn't know about DO
deploySvc := deploy.NewService(regions, store, queue)
Adding AWS later means writing adapter/aws/*.go and registering a new region. Zero changes to core.
Cross-references
Where adapters live in the tree → §9 · integrations (the
other pattern — all active at once) → §11 · the Region
struct that binds a port set → §12 · the BuildService port's
full contract → Starforge §16.3.