Skip to content

Checking access...

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 cert

IC boundary nodes:

  1. Receive requests for custom domains
  2. Query DNS for _canister-id.<domain> TXT record
  3. Route traffic to the specified canister
  4. Automatically provision Let's Encrypt SSL certificates

Current Domain Configuration

Active Suite Domains

DomainCanisterCanister IDStatus
staging-think-tank.helloworlddao.comthink-tank-suitewnfjk-biaaa-aaaao-a6dhq-cai✅ Working
staging-governance.helloworlddao.comgovernance-suitewkep6-mqaaa-aaaao-a6dha-cai✅ Working
staging-ottercamp.helloworlddao.comotter-camp-suitedzt3i-sqaaa-aaaao-a6uaa-cai✅ Working
staging-portal.helloworlddao.comdao-suited6s54-7iaaa-aaaao-a6uaq-cai✅ Working
staging-admin.helloworlddao.comdao-admin-suitedxrwa-jaaaa-aaaao-a6uba-cai✅ Working
www.helloworlddao.commarketing-suited5fe6-hqaaa-aaaao-a6t5q-cai✅ Working
staging-docs.helloworlddao.comdocs_site4t67s-qaaaa-aaaao-a62ga-cai✅ Working

Legacy Monolith Domains (Archived)

DomainCanisterCanister IDStatus
staging.helloworlddao.comwww (frontend)vlmti-wqaaa-aaaad-acoiq-cai⚠️ Archived

Step 1: Get Canister ID

bash
# 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-cai

Step 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: 600

Note: IC boundary nodes are at multiple IPs. Using icp0.io as CNAME is preferred:

Type: CNAME
Name: <subdomain>
Value: icp0.io
TTL: 600
Type: TXT
Name: _canister-id.<subdomain>
Value: <canister-id>
TTL: 600

Example: 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: 600

Example: 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: 600

Step 3: Verify DNS Propagation

Wait for DNS propagation (typically 1-2 hours, maximum 24 hours), then verify:

bash
# 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.

New Domain Registration

For a new domain (first time setup):

bash
# Validate configuration first
curl -s "https://icp0.io/custom-domains/v1/staging-admin.helloworlddao.com/validate" | jq .

# Register the domain (POST for new domains)
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 .

Domain Transfer (Moving Between Canisters)

If you need to transfer a domain from one canister to another:

bash
# Update DNS records first (change _canister-id TXT record to new canister ID)
# Wait for DNS propagation (1-2 hours typically, max 24 hours)

# Transfer the domain (PATCH for existing domains)
curl -s -X PATCH "https://icp0.io/custom-domains/v1/YOUR_DOMAIN" | jq .

# IMPORTANT: Also remove domain from old canister's .well-known/ic-domains file
# The domain must be removed from the old canister to complete the transfer

Note: IC boundary nodes now auto-discover domains from DNS records, but explicit registration via the API is still best practice to ensure proper SSL certificate provisioning.

Expected Registration Flow

  1. validation_status: "valid" - DNS is correctly configured
  2. registration_status: "registering" - Processing request
  3. registration_status: "registered" - Complete, SSL will be provisioned

Step 5: Verify SSL Certificate

After registration completes, IC will provision SSL. Verify:

bash
# 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.com

If 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

bash
# Test HTTPS
curl -s -o /dev/null -w "%{http_code}\n" https://staging-admin.helloworlddao.com

# Should return: 200

Troubleshooting

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, or domain transfer incomplete

Solution:

  1. Check registration status:
    bash
    curl -s "https://icp0.io/custom-domains/v1/YOUR_DOMAIN" | jq .
  2. If not_found, register the domain:
    bash
    curl -s -X POST "https://icp0.io/custom-domains/v1/YOUR_DOMAIN" | jq .
  3. If transferring from another canister:
    bash
    # Use PATCH instead of POST for existing domains
    curl -s -X PATCH "https://icp0.io/custom-domains/v1/YOUR_DOMAIN" | jq .
    
    # Also remove domain from old canister's .well-known/ic-domains file
  4. Wait for registration_status: "registered"
  5. 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:

  1. Verify TXT record: dig _canister-id.<domain> TXT +short
  2. If missing, add the TXT record in DNS
  3. Wait 10-15 minutes for propagation
  4. Re-run validation and registration

Problem: DNS Not Resolving

Symptom: dig <domain> +short returns nothing

Cause: A/CNAME record missing

Solution:

  1. Add A record pointing to 23.142.184.129 or CNAME to icp0.io
  2. Wait 5-10 minutes for propagation

Problem: HTTP 308 Redirect Loop

Symptom: Constant redirects, never loads

Cause: Usually a caching issue

Solution:

  1. Clear browser cache
  2. Try incognito/private window
  3. Try curl -L to follow redirects

Problem: Canister Returns 404

Symptom: Domain works but shows 404

Cause: Canister assets not deployed or wrong path

Solution:

  1. Verify canister has assets: dfx canister --network ic info <name>
  2. Redeploy if needed: dfx deploy --network ic <name>

Fallback: Raw IC URL

If custom domain isn't working, use the raw IC URL:

CanisterRaw URL
Foundery OS Suitehttps://wnfjk-biaaa-aaaao-a6dhq-cai.icp0.io/
Governance Suitehttps://wkep6-mqaaa-aaaao-a6dha-cai.icp0.io/
Marketing Suitehttps://d5fe6-hqaaa-aaaao-a6t5q-cai.icp0.io/
Otter Camp Suitehttps://dzt3i-sqaaa-aaaao-a6uaa-cai.icp0.io/
DAO Suitehttps://d6s54-7iaaa-aaaao-a6uaq-cai.icp0.io/
DAO Admin Suitehttps://dxrwa-jaaaa-aaaao-a6uba-cai.icp0.io/
Docs Sitehttps://4t67s-qaaaa-aaaao-a62ga-cai.icp0.io/

DNS Records Checklist

Staging Environment

Record TypeNameValueStatus
CNAMEstaging-think-tankicp0.io
TXT_canister-id.staging-think-tankwnfjk-biaaa-aaaao-a6dhq-cai
CNAMEstaging-governanceicp0.io
TXT_canister-id.staging-governancewkep6-mqaaa-aaaao-a6dha-cai
CNAMEstaging-ottercampicp0.io
TXT_canister-id.staging-ottercampdzt3i-sqaaa-aaaao-a6uaa-cai
CNAMEstaging-portalicp0.io
TXT_canister-id.staging-portald6s54-7iaaa-aaaao-a6uaq-cai
CNAMEstaging-adminicp0.io
TXT_canister-id.staging-admindxrwa-jaaaa-aaaao-a6uba-cai
CNAMEstaging-docsicp0.io
TXT_canister-id.staging-docs4t67s-qaaaa-aaaao-a62ga-cai

Production Environment

Record TypeNameValueStatus
CNAMEwwwicp0.io
TXT_canister-id.wwwd5fe6-hqaaa-aaaao-a6t5q-cai
CNAMEfounderyicp0.io⚠️ Configure when ready
TXT_canister-id.founderywnfjk-biaaa-aaaao-a6dhq-cai⚠️ Configure when ready
CNAMEgovernanceicp0.io⚠️ Configure when ready
TXT_canister-id.governancewkep6-mqaaa-aaaao-a6dha-cai⚠️ Configure when ready
CNAMEottercampicp0.io⚠️ Configure when ready
TXT_canister-id.ottercampdzt3i-sqaaa-aaaao-a6uaa-cai⚠️ Configure when ready
CNAMEportalicp0.io⚠️ Configure when ready
TXT_canister-id.portald6s54-7iaaa-aaaao-a6uaq-cai⚠️ Configure when ready
CNAMEadminicp0.io⚠️ Configure when ready
TXT_canister-id.admindxrwa-jaaaa-aaaao-a6uba-cai⚠️ Configure when ready
CNAMEdocsicp0.io⚠️ Configure when ready
TXT_canister-id.docs4t67s-qaaaa-aaaao-a62ga-cai⚠️ Configure when ready

Estimated Time

  • DNS record addition: 5 minutes
  • DNS propagation: 1-2 hours typically (max 24 hours)
  • API registration: 1-2 minutes
  • SSL certificate provisioning: 5-10 minutes
  • Total: ~2-3 hours (wait for DNS), then 5-10 minutes for SSL

Hello World Co-Op DAO