IC Custom Domain Setup Runbook β
Overview β
This runbook documents how to configure custom domains for Internet Computer canisters. IC uses DNS TXT records to map custom domains to canister IDs.
Prerequisites β
- Access to DNS management (GoDaddy for helloworlddao.com)
- Canister deployed to IC mainnet
- Canister ID (get via
dfx canister --network ic id <canister-name>)
How IC Custom Domains Work β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β User Browser ββββββΆβ IC Boundary ββββββΆβ Canister β
β β β Nodes β β β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β β
β 1. Request to β 2. Lookup TXT record
β custom domain β _canister-id.domain
β β
β β 3. Route to canister
β β + generate SSL certIC boundary nodes:
- Receive requests for custom domains
- Query DNS for
_canister-id.<domain>TXT record - Route traffic to the specified canister
- Automatically provision Let's Encrypt SSL certificates
Current Domain Configuration β
| Domain | Canister | Canister ID | Status |
|---|---|---|---|
| staging.helloworlddao.com | www (frontend) | vlmti-wqaaa-aaaad-acoiq-cai | β Working |
| staging-admin.helloworlddao.com | admin | ehbll-kiaaa-aaaac-qc2aa-cai | β Working |
| www.helloworlddao.com | www (frontend) | vlmti-wqaaa-aaaad-acoiq-cai | β οΈ Not configured |
Step 1: Get Canister ID β
# Set environment to suppress warnings
export DFX_WARNING=-mainnet_plaintext_identity
# Get canister ID
cd /home/coby/git/frontend
dfx canister --network ic id admin
# Output: ehbll-kiaaa-aaaac-qc2aa-cai
dfx canister --network ic id www
# Output: vlmti-wqaaa-aaaad-acoiq-caiStep 2: Configure DNS Records β
Required Records β
For each custom domain, add these DNS records in GoDaddy:
A Record (Points domain to IC) β
Type: A
Name: <subdomain> (e.g., "staging-admin" or "staging")
Value: 23.142.184.129
TTL: 600Note: IC boundary nodes are at multiple IPs. Using icp0.io as CNAME is preferred:
Type: CNAME
Name: <subdomain>
Value: icp0.io
TTL: 600TXT Record (Links domain to canister) β
Type: TXT
Name: _canister-id.<subdomain>
Value: <canister-id>
TTL: 600Example: staging-admin.helloworlddao.com β
# Option 1: CNAME (preferred)
Type: CNAME
Name: staging-admin
Value: icp0.io
TTL: 600
# Required: Canister ID TXT record
Type: TXT
Name: _canister-id.staging-admin
Value: ehbll-kiaaa-aaaac-qc2aa-cai
TTL: 600Example: www.helloworlddao.com (Production) β
# Option 1: CNAME
Type: CNAME
Name: www
Value: icp0.io
TTL: 600
# Required: Canister ID TXT record
Type: TXT
Name: _canister-id.www
Value: vlmti-wqaaa-aaaad-acoiq-cai
TTL: 600Step 3: Verify DNS Propagation β
Wait 5-15 minutes for DNS propagation, then verify:
# Check A/CNAME record
dig staging-admin.helloworlddao.com +short
# Should return: icp0.io or 23.142.184.129
# Check TXT record (critical!)
dig _canister-id.staging-admin.helloworlddao.com TXT +short
# Should return: "ehbll-kiaaa-aaaac-qc2aa-cai"Step 4: Register Domain with IC API β
CRITICAL: DNS records alone are not enough. You must explicitly register the domain with IC's custom domain API:
# Validate configuration first
curl -s "https://icp0.io/custom-domains/v1/staging-admin.helloworlddao.com/validate" | jq .
# Register the domain (required!)
curl -s -X POST "https://icp0.io/custom-domains/v1/staging-admin.helloworlddao.com" | jq .
# Check registration status
curl -s "https://icp0.io/custom-domains/v1/staging-admin.helloworlddao.com" | jq .Expected registration flow:
validation_status: "valid"- DNS is correctly configuredregistration_status: "registering"- Processing requestregistration_status: "registered"- Complete, SSL will be provisioned
Step 5: Verify SSL Certificate β
After registration completes, IC will provision SSL. Verify:
# Check SSL certificate
echo | openssl s_client -connect staging-admin.helloworlddao.com:443 \
-servername staging-admin.helloworlddao.com 2>&1 | grep "subject="
# Should return: subject=CN = staging-admin.helloworlddao.comIf SSL shows wrong domain (e.g., ai.icpex.org):
- TXT record is missing or incorrect
- DNS hasn't propagated yet
- Wait 10-15 minutes and retry
Step 6: Test the Domain β
# Test HTTPS
curl -s -o /dev/null -w "%{http_code}\n" https://staging-admin.helloworlddao.com
# Should return: 200Troubleshooting β
Problem: SSL Certificate Mismatch (Wrong Domain) β
Symptom: Browser shows SSL error, certificate for wrong domain (e.g., ai.icpex.org)
Cause: Domain was never registered with IC's custom domain API
Solution:
- Check registration status:bash
curl -s "https://icp0.io/custom-domains/v1/YOUR_DOMAIN" | jq . - If
not_found, register the domain:bashcurl -s -X POST "https://icp0.io/custom-domains/v1/YOUR_DOMAIN" | jq . - Wait for
registration_status: "registered" - Certificate will be provisioned automatically
Problem: _canister-id TXT Record Missing β
Symptom: Validation fails, can't register domain
Cause: _canister-id TXT record missing or incorrect
Solution:
- Verify TXT record:
dig _canister-id.<domain> TXT +short - If missing, add the TXT record in DNS
- Wait 10-15 minutes for propagation
- Re-run validation and registration
Problem: DNS Not Resolving β
Symptom: dig <domain> +short returns nothing
Cause: A/CNAME record missing
Solution:
- Add A record pointing to
23.142.184.129or CNAME toicp0.io - Wait 5-10 minutes for propagation
Problem: HTTP 308 Redirect Loop β
Symptom: Constant redirects, never loads
Cause: Usually a caching issue
Solution:
- Clear browser cache
- Try incognito/private window
- Try
curl -Lto follow redirects
Problem: Canister Returns 404 β
Symptom: Domain works but shows 404
Cause: Canister assets not deployed or wrong path
Solution:
- Verify canister has assets:
dfx canister --network ic info <name> - Redeploy if needed:
dfx deploy --network ic <name>
Fallback: Raw IC URL β
If custom domain isn't working, use the raw IC URL:
| Canister | Raw URL |
|---|---|
| Frontend (www) | https://vlmti-wqaaa-aaaad-acoiq-cai.icp0.io/ |
| Admin | https://ehbll-kiaaa-aaaac-qc2aa-cai.icp0.io/ |
DNS Records Checklist β
Staging Environment β
| Record Type | Name | Value | Status |
|---|---|---|---|
| CNAME/A | staging | icp0.io | β |
| TXT | _canister-id.staging | vlmti-wqaaa-aaaad-acoiq-cai | β |
| CNAME/A | staging-admin | icp0.io | β |
| TXT | _canister-id.staging-admin | ehbll-kiaaa-aaaac-qc2aa-cai | β |
Production Environment β
| Record Type | Name | Value | Status |
|---|---|---|---|
| CNAME/A | www | icp0.io | β οΈ Configure when ready |
| TXT | _canister-id.www | vlmti-wqaaa-aaaad-acoiq-cai | β οΈ Configure when ready |
| CNAME/A | admin | icp0.io | β οΈ Future |
| TXT | _canister-id.admin | TBD | β οΈ Future |
Related Documentation β
Estimated Time β
- DNS record addition: 5 minutes
- DNS propagation: 5-15 minutes
- SSL certificate provisioning: 5-10 minutes
- Total: ~15-30 minutes