Skip to content

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:

  1. Check whether the domain is already in your Porkbun account
  2. Register it if not (deducted from your Porkbun account balance)
  3. Create or update DNS records declared in the records array
  4. 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.


Porkbun requires two keys. Enable API access at porkbun.com/account/api first.

Terminal window
# Primary API key (pk1_...)
ss vault set-key porkbun api_key pk1_your_key_here
# Secret key (sk1_...) — stored as a project credential
ss vault set PORKBUN_SECRET_KEY sk1_your_secret_here
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_NAME
Terminal window
ss provision # or ss deploy --env=prod

The provisioner prints what it’s doing:

+ domain porkbun domain myapp.io registered and DNS records created

On subsequent runs it’s idempotent — it verifies the domain is active and updates records if the content changed.


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_NAME

depends_on: [api] ensures Fly runs first and FLY_IP is in the vault before the DNS provisioner tries to resolve it.


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.io
You writeWhat 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)

KeyWhere to storeValue
porkbun.api_keyProvider keypk1_... (from porkbun.com/account/api)
PORKBUN_SECRET_KEYProject credentialsk1_... (shown once at key creation)
Terminal window
ss vault set-key porkbun api_key <pk1_...>
ss vault set PORKBUN_SECRET_KEY <sk1_...>

Terminal window
ss provision --status
✓ domain porkbun domain myapp.io active — expires 2026-04-28

Or via MCP:

starsystem_provision_status
→ { serviceId: "domain", provider: "porkbun", healthy: true, message: "domain myapp.io active — expires 2026-04-28" }

Terminal window
ss provision --destroy --service=domain

This 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.


Browse Porkbun domain pricing before committing:

Terminal window
ss catalog --category=dns
SERVICES & 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
...

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