Docs · Custom domains

Custom domains.

Two paths: a *.remoco.dev subdomain (instant, free, no DNS work on your side) or your own apex like api.acme.com (Cloudflare for SaaS handles cert provisioning; you point a CNAME at remoco).

Path 1 · remoco.dev subdomain

Fastest path for demos, internal tools, and shareable previews. Remoco creates the DNS record on the remoco.dev zone and routes traffic through the shared cloudflared tunnel to whatever backend you specify.

$ remoco create domain my-app --spec='{"hostname":"my-app.remoco.dev","origin":"cloud-run-myapp"}'
# DNS live in a few seconds
# cloudflared ingress materialized by the sync daemon (~30s)
# https://my-app.remoco.dev/ → cloud-run-myapp

Origin can be a remoco resource id (cloud-run-myapp, workstation-wiley-1) or a full URL (https://internal.example.com).

The cloudflared tunnel runs as a Cloud Run service with two replicas. Loss of any single replica is invisible to clients. See Architecture.

Path 2 · Your apex via Cloudflare for SaaS

For customer-facing branding (api.acme.com, app.startup.io). Remoco mints a Cloudflare Custom Hostname; you add a CNAME at your DNS provider; Cloudflare provisions SSL on your behalf.

$ remoco create domain acme-api --spec='{"hostname":"api.acme.com","origin":"cloud-run-acme-api"}'
{
  "id": "domain-acme-api",
  "state": "pending",
  "meta": {
    "mode": "custom-hostname",
    "status": "pending_verification",
    "verification_record": {
      "name": "_acme-challenge.api.acme.com",
      "type": "TXT",
      "value": "..."
    }
  }
}

Add the verification TXT record at your DNS provider. The reconciler polls Cloudflare every 5 min and flips state from pending to running once the cert issues. Then add a CNAME from api.acme.com to customers.remoco.dev to send traffic through.

Operator setup (once per remoco install)

Cloudflare for SaaS is a paid add-on on the Cloudflare account that owns the remoco.dev zone. To enable:

  1. Visit Cloudflare dashboard → SSL/TLS → Custom Hostnames
  2. Click Enable Cloudflare for SaaS
  3. Choose a plan (Free tier covers 100 hostnames; growth tiers from there)
  4. Mint an API token with scopes Zone.SSL: Edit + Zone.Custom Hostnames: Edit + Zone.DNS: Edit
  5. Drop the token: gcloud secrets versions add remoco-cloudflare-api-token --data-file=-
  6. Redeploy the API: gcloud run services update remoco-api --update-env-vars=CF_TOKEN_REV=v2

Until the dashboard step is done, custom-hostname creates land in status: "pending_cf_config" with a clear note in meta.note. Subdomain creates keep working — they only need Zone.DNS: Edit.

Bring your own cert (CNAME-only path)

If you don't want Cloudflare in your TLS path, skip the custom-hostname API and just CNAME at your DNS provider. Configure your origin (Cloud Run, Vercel, Fly, your own VM) to terminate TLS.

# at your DNS provider
api.acme.com CNAME customers.remoco.dev

# on your origin: terminate TLS for api.acme.com
# (e.g. Cloud Run domain mappings, Vercel certs, ACME on your VM)

This path is faster but loses Cloudflare's caching, WAF, and analytics for that hostname. Best for staging or internal tools.

Destroying a domain

Removes the upstream Cloudflare resource and the corresponding row in remoco. Subdomain deletes also remove the DNS record from remoco.dev.

$ remoco destroy domain-acme-api
# cf custom hostname removed
# resource state=destroyed

Listing domains

The Networks tab in the console shows all custom domains for the active org. The CLI:

$ remoco resources --kind=domain

Limits