Skip to content

feat(domains): auto-assign per-project subdomains when PANEL_BASE_DOMAIN is set - #46

Open
flavioduque wants to merge 1 commit into
alanfrigo:mainfrom
flavioduque:feat/auto-project-subdomain
Open

flavioduque wants to merge 1 commit into
alanfrigo:mainfrom
flavioduque:feat/auto-project-subdomain

Conversation

@flavioduque

Copy link
Copy Markdown

Problem

Every new Supabase instance needs its API and Studio domains typed in by hand, plus one CNAME per domain at the DNS provider, before it is reachable over HTTPS. Operators who already own a wildcard record (*.supa.example.com → server) still have to repeat this for every instance.

Fix

New optional env var PANEL_BASE_DOMAIN. When it is set, createProject assigns at creation time:

  • API: api-<slug>.<PANEL_BASE_DOMAIN>
  • Studio: <slug>.<PANEL_BASE_DOMAIN> (served through Kong's authenticated dashboard route, like manual Studio domains)

Then it does the same things as the manual PUT /api/projects/[id]/domain:

  • saves both domains with their DNS-check result;
  • points API_EXTERNAL_URL / SUPABASE_PUBLIC_URL at the HTTPS API domain;
  • generates the routing through generateProjectTraefikConfig (file provider standalone, Kong labels on Dokploy).

Routing is written last, so a failure earlier in the step goes through the existing creation rollback.

  • autoProjectDomains() lives next to validDnsTarget() in src/lib/dns-target.ts. Hosts that are not valid DNS names (for example a slug that starts with -) are skipped, and that instance stays on manual domains.
  • PANEL_BASE_DOMAIN is passed through in docker-compose.yml (Dokploy) and the install.sh compose. The README documents the wildcard record.
  • Without PANEL_BASE_DOMAIN, nothing changes.

Verification

  • tests/auto-subdomain.test.ts: it was written first and failed 3/3 (autoProjectDomains is not a function); after the change it passes 3/3. It covers: base set → both hosts, lower-cased and trimmed; base unset/empty → null (old behaviour); invalid slug → null. A mutation check (removing the hostname validation) makes the third test fail.
  • npm test: 14 pass, 0 fail, 3 skipped (opt-in integration tests). npm run lint is clean. npx tsc --noEmit passes.

Not verified

  • The createProject wiring (DB update, env update, Traefik generation) is checked only by reading the code and by type-checking. It was not executed, because it needs Postgres and a cloned Supabase template.
  • Real wildcard DNS, Let's Encrypt issuance and an end-to-end HTTPS request to a new instance.
  • Branch instances (provisionProjectFiles) do not get automatic subdomains; that is out of scope here.

🤖 Generated with Claude Code

…AIN is set

With a wildcard DNS record (*.base) pointing at the proxy, every new
instance gets api-<slug>.<base> (API) and <slug>.<base> (Studio, served
through Kong's authenticated route) at creation time: domains are saved
with their DNS check result, API_EXTERNAL_URL/SUPABASE_PUBLIC_URL are
pointed at the HTTPS API domain, and the Traefik routing (file provider
or Dokploy labels) is generated through the existing helpers.

Without PANEL_BASE_DOMAIN nothing changes. Slugs that are not valid
hostname labels are skipped and stay on manual domains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant