Skip to content

Custom Domain

CP users can attach their own domain name to a deployed service. Once configured, the domain serves the service over HTTPS with an automatically provisioned Let's Encrypt certificate.

How It Works

user domain (e.g. dashboard.example.com)
    │  CNAME (DNS only)

cpctl.app


edge (Let's Encrypt cert provisioned per hostname, auto-renewed)


Kubernetes cluster
  Traefik Ingress (routes by Host header)


Service pod (e.g. cp-dashboard)

User Setup

Add a single DNS record at your domain registrar or DNS provider:

NameTypeTargetProxy
dashboardCNAMEcpctl.appDNS only (grey cloud)

No Cloudflare account required. Works with any DNS provider. The record must be DNS only — do not enable proxying.

API

Attach a domain

http
POST /v1/services/:service/domains
Authorization: Bearer <cp-api-token>
Content-Type: application/json

{
  "hostname": "dashboard.koraccel.kr"
}

What happens: The platform verifies the CNAME, provisions a Let's Encrypt certificate for the hostname, and configures the edge servers to serve the domain over HTTPS. This takes about a minute.

Response:

json
{
  "hostname": "dashboard.koraccel.kr",
  "status": "active",
  "service": "cp-dashboard",
  "created_at": "2026-07-04T10:52:36.153Z"
}

Skip DNS check (for testing):

json
{ "hostname": "dashboard.koraccel.kr", "skip_dns": true }

List domains

http
GET /v1/services/:service/domains
Authorization: Bearer <cp-api-token>
json
{
  "domains": [
    { "hostname": "cp-dashboard.computeportal.io", "status": "active", "created_at": null },
    { "hostname": "dashboard.koraccel.kr", "status": "active", "created_at": null }
  ]
}

Remove a domain

http
DELETE /v1/services/:service/domains/:hostname
Authorization: Bearer <cp-api-token>

Returns 204 No Content. The default <service>.cpctl.app domain cannot be removed.

What happens on the server:

  1. Removes the hostname from the Traefik Ingress routing rules
  2. Removes the TLS certificate entry for the hostname

Certificates are not explicitly revoked on removal — they expire naturally after 90 days.

CLI

bash
cpctl domain add <service> <domain>        # attach a domain
cpctl domain list <service>                # list attached domains
cpctl domain status <service> <domain>     # check DNS and TLS status
cpctl domain remove <service> <domain>     # detach a domain

domain add

Before running this, add a CNAME record at your DNS provider:

NameTypeTargetProxy
dashboardCNAMEcpctl.appDNS only (grey cloud)

Then attach the domain:

bash
cpctl domain add my-service dashboard.example.com
✓ Domain dashboard.example.com attached to my-service

domain   dashboard.example.com
service  my-service
status   active
tls      provisioning

TLS is provisioned automatically via Let's Encrypt within a minute or two.

If DNS hasn't propagated yet, use --skip-dns to bypass the CNAME check:

bash
cpctl domain add my-service dashboard.example.com --skip-dns

domain list

bash
cpctl domain list my-service
DOMAIN                     STATUS   TLS          CREATED
my-service.cpctl.app       active   active        2026-08-21T04:52:23.000Z
dashboard.example.com      active   provisioning  2026-08-21T04:52:23.000Z

domain status

bash
cpctl domain status my-service dashboard.example.com
domain          dashboard.example.com
status          active
tls             yes
dns_configured  yes
cname_target    cpctl.app
created_at      2026-07-01T10:00:00Z

domain remove

bash
cpctl domain remove my-service dashboard.example.com

The default <service>.cpctl.app domain cannot be removed.

MCP Tools

ToolDescription
cp_domain_addAttach a custom hostname to a service
cp_domain_listList all hostnames attached to a service
cp_domain_removeDetach a custom hostname from a service

Infrastructure

ComponentValue
CNAME targetcpctl.app
TLSLet's Encrypt, issued per hostname, provisioned automatically
RoutingTraefik Ingress, Host-header rules

GPU Compute Platform