How tdomains works
A multi-tenant domain platform for Coder workspaces. Auto-TLS, path routing, zero exposed ports.
The mental model
Your code lives in a Coder workspace (a Docker container) and listens on a port — say 3000 — inside the container. That port is never exposed publicly. Instead, you bind a public hostname → workspace → port, and we provide:
- Automatic TLS via Let's Encrypt (issued on first hit)
- Path-based routing (/api/* → :8000, default → :3000)
- WebSocket pass-through, redirect & cookie hygiene
- Audit log + soft-delete
Pretty subdomain vs. custom domain
Pretty subdomain — anything ending in .code.tur.al (except the reserved apps.code.tur.al). We own the DNS so it's live the moment you submit the form. Use for staging, demos, internal tools.
Custom domain — your own domain (e.g. myapp.com). After creating, add the displayed A record at your registrar. Once DNS points to us, click Verify now. TLS is provisioned on the first browser hit.
Path routes
Single-port apps don't need routes. For split frontend + backend:
/api/* → :8000 /_event* → :8000 /socket.io/* → :8000 default → :3000
- /api/* matches /api/... (NOT /api itself)
- /api* matches /api, /apis, /api/foo
- /admin exact match only
Longest matching path wins.
Security model
- Your Coder session token is stored in an HMAC-signed, HttpOnly, Secure, SameSite=Strict cookie. Never on disk.
- Token validated against Coder on every request.
- You can only see/manage your own domains.
- Every mutating form carries a CSRF token tied to your session.
- Workspace ports are never exposed publicly — only via verified hostnames.
- Caddy issues TLS on-demand and blocks unknown hosts (validator enforces registry membership).
- Strict CSP: no inline scripts, no external resources, frame-ancestors 'none'.
CLI
The same functionality is in tc-domain:
curl -fsSL https://domains.code.tur.al/install | bash export PATH="$HOME/.local/bin:$PATH" tc-domain login tc-domain add hello.YOU.code.tur.al --workspace YOUR_WS --port 3000
Also: tc-domain import-caddyfile FILE --workspace WS for bulk migration from an existing Caddyfile.