Domains & DNS — Porkbun
Starsystem can register domain names and wire DNS records as part of a normal ss deploy or ss provision run. When a service has provision.provider: porkbun, the deploy runner will:
- Check whether the domain is already in your Porkbun account
- Register it if not (deducted from your Porkbun account balance)
- Create or update DNS records declared in the
recordsarray - Write
DOMAIN_NAME(or your chosen env var) to the vault
DNS record content can reference other vault values using {{ vault('service.ENV_VAR') }} — so you can point an A record at a Fly.io IP that was itself provisioned in the same run.
Quick start
Section titled “Quick start”1. Store credentials in the vault
Section titled “1. Store credentials in the vault”Porkbun requires two keys. Enable API access at porkbun.com/account/api first.
# Primary API key (pk1_...)ss vault set-key porkbun api_key pk1_your_key_here
# Secret key (sk1_...) — stored as a project credentialss vault set PORKBUN_SECRET_KEY sk1_your_secret_here2. Add a dns service to your YAML
Section titled “2. Add a dns service to your YAML”services: domain: type: dns name: My Domain provision: provider: porkbun domain: myapp.io records: - type: A name: "@" content: "203.0.113.42" - type: CNAME name: www content: myapp.io credential_env: DOMAIN_NAME3. Deploy
Section titled “3. Deploy”ss provision # or ss deploy --env=prodThe provisioner prints what it’s doing:
+ domain porkbun domain myapp.io registered and DNS records createdOn subsequent runs it’s idempotent — it verifies the domain is active and updates records if the content changed.
Wiring DNS to other services
Section titled “Wiring DNS to other services”The most powerful pattern is pointing DNS records at resources provisioned in the same run. Use the {{ vault('service.ENV_VAR') }} syntax in record content:
services: api: type: app provision: provider: fly image: ghcr.io/my-org/api:latest credential_env: API_URL # Fly writes FLY_IP to vault
domain: type: dns name: Domain & DNS depends_on: [api] # ensure api is provisioned first provision: provider: porkbun domain: myapp.io records: - type: A name: "@" content: "{{ vault('api.FLY_IP') }}" # resolved at deploy time - type: CNAME name: www content: myapp.io - type: TXT name: "@" content: "v=spf1 include:_spf.google.com ~all" credential_env: DOMAIN_NAMEdepends_on: [api] ensures Fly runs first and FLY_IP is in the vault before the DNS provisioner tries to resolve it.
All options
Section titled “All options”provision: provider: porkbun domain: myapp.io # required — the domain to register/manage years: 1 # registration period (1–10, default: 1) auto_renew: true # auto-renew before expiry (default: true) whois_privacy: true # free WHOIS privacy via Porkbun (default: true) credential_env: DOMAIN_NAME # vault key written after provisioning records: - type: A # A | AAAA | CNAME | MX | TXT | NS | SRV | CAA | HTTPS name: "@" # subdomain or "@" / "" for root content: "1.2.3.4" ttl: 600 # seconds (minimum 600, default: 600) - type: MX name: "@" content: "mail.myapp.io" prio: 10 # priority — required for MX and SRV records - type: CNAME name: www content: myapp.ioRecord name conventions
Section titled “Record name conventions”| You write | What it means |
|---|---|
"@" | Root of the domain (myapp.io) |
"" | Also root (Porkbun API convention) |
"www" | www.myapp.io |
"api" | api.myapp.io |
"myapp.io" | Also root (domain suffix stripped automatically) |
Vault keys required
Section titled “Vault keys required”| Key | Where to store | Value |
|---|---|---|
porkbun.api_key | Provider key | pk1_... (from porkbun.com/account/api) |
PORKBUN_SECRET_KEY | Project credential | sk1_... (shown once at key creation) |
ss vault set-key porkbun api_key <pk1_...>ss vault set PORKBUN_SECRET_KEY <sk1_...>Status checks
Section titled “Status checks”ss provision --status✓ domain porkbun domain myapp.io active — expires 2026-04-28Or via MCP:
starsystem_provision_status→ { serviceId: "domain", provider: "porkbun", healthy: true, message: "domain myapp.io active — expires 2026-04-28" }Destroying DNS records
Section titled “Destroying DNS records”ss provision --destroy --service=domainThis deletes the DNS records created by Starsystem. It does not cancel the domain registration — Porkbun’s API does not expose a registration cancellation endpoint, and accidental domain loss is permanent. Manage renewal at porkbun.com/account.
Using the catalog
Section titled “Using the catalog”Browse Porkbun domain pricing before committing:
ss catalog --category=dnsSERVICES & PRICING — drag onto canvas or reference in YAML
Porkbun Domains .com $0.88/mo · $9.73/yr first year, $10.57/yr renewal .io $2.99/mo · $35.88/yr renewal .dev $1.04/mo · $12.49/yr renewal .ai $5.83/mo · $69.98/yr renewal ...MCP tool
Section titled “MCP tool”Agents can browse the catalog and provision domains:
starsystem_catalog category=dns→ returns Porkbun domain options with pricing
starsystem_add_service→ add a dns service with porkbun provider
starsystem_provision_service service_id=domain→ register and wire DNS
starsystem_provision_status→ verify domain is active