# Connect a Domain

**Page:** foundation/proxy/connect-domain

[Download Raw Markdown](./foundation/proxy/connect-domain.md)

---

# Connect a Domain

**Use your own domain with Hoody containers.** Point `api.mycompany.com` to your container services and we handle the SSL automatically.

After creating [proxy aliases](./aliases/) for memorable URLs, you can take the final step: **connecting your own custom domain**.

---

## API Endpoints Summary

**Official Technical Reference:**

Custom domains use DNS CNAMEs to proxy aliases (no direct API calls needed for DNS). However, you configure aliases via:

**Alias Management (CNAME Targets):**
- **[POST /api/v1/proxy/aliases](/api/proxy-aliases/)** - Create alias (used as CNAME target)
- **[GET /api/v1/proxy/aliases](/api/proxy-aliases/)** - List your aliases
- **[GET /api/v1/proxy/aliases/\{id\}](/api/proxy-aliases/)** - Get alias details
- **[PATCH /api/v1/proxy/aliases/\{id\}](/api/proxy-aliases/)** - Update alias configuration
- **[DELETE /api/v1/proxy/aliases/\{id\}](/api/proxy-aliases/)** - Delete alias

**SSL & Domains:**
- SSL certificates are provisioned automatically by Hoody when DNS CNAME is detected
- No API calls needed—just point CNAME to your alias URL
- Let's Encrypt certificates auto-renew every 90 days

---

## How It Works

**The complete flow is simple:**

```
1. Create a proxy alias → my-app.node-us.containers.hoody.icu
2. CNAME your domain to the alias → api.mycompany.com → my-app.node-us.containers.hoody.icu
3. SSL certificate automatically provisioned → https://api.mycompany.com (live)
```

**That's it.** No certificate management. No proxy configuration. No server setup. Just a DNS record.

---

## The CNAME Target Pattern

**Your custom domain points to your proxy alias:**

<div style="margin: 1.5rem 0;">

**Step 1: Create the alias** (CNAME target)


  
    ```bash
    # Create alias as CNAME target for your custom domain
    hoody proxy create --container-id $CONTAINER_ID --alias myapp-prod --program http --index 1
    ```
  
  
    ```typescript
    const alias = await client.api.proxyAliases.create({
      container_id: CONTAINER_ID,
      alias: 'myapp-prod',
      program: 'http',
      index: 1
    });
    console.log(alias.data.url);
    // https://myapp-prod.node-us.containers.hoody.icu
    ```
  
  
    ```bash
    curl -X POST "https://api.hoody.icu/api/v1/proxy/aliases" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "container_id": "'$CONTAINER_ID'",
        "alias": "myapp-prod",
        "program": "http",
        "index": 1
      }'
    ```
  




**Gives you:** `https://myapp-prod.node-us.containers.hoody.icu`

**Step 2: Add CNAME record** at your DNS provider

```
api.mycompany.com  CNAME  myapp-prod.node-us.containers.hoody.icu
```

**Step 3: Automatic SSL**

Hoody detects the CNAME, provisions Let's Encrypt certificate for `api.mycompany.com`, and routes traffic:

```
User requests:
https://api.mycompany.com
  ↓ (DNS CNAME)
https://myapp-prod.node-us.containers.hoody.icu
  ↓ (Hoody Proxy routes)
Container's HTTP service
```

</div>

**Within 5-10 minutes:** Your domain is live with HTTPS.

---

## Complete Setup Guide

### Prerequisites

**You need:**
- A proxy alias (create via `POST /api/v1/proxy/aliases`)
- Access to your domain's DNS settings
- Your server name (e.g., `node-us`, `node-eu`)

### Step-by-Step: Subdomain (Recommended)

**Subdomains are easier and more flexible than root domains.**


  
    
      
        ```bash
        # Create the CNAME target alias
        hoody proxy create --container-id $CONTAINER_ID \
          --alias production-api --program http --index 1 \
          --target-path /api/v1 --allow-path-override
        ```
      
      
        ```typescript
        const alias = await client.api.proxyAliases.create({
          container_id: CONTAINER_ID,
          alias: 'production-api',
          program: 'http',
          index: 1,
          target_path: '/api/v1',
          allow_path_override: true
        });
        ```
      
      
        ```bash
        curl -X POST "https://api.hoody.icu/api/v1/proxy/aliases" \
          -H "Authorization: Bearer $TOKEN" \
          -H "Content-Type: application/json" \
          -d '{
            "container_id": "'$CONTAINER_ID'",
            "alias": "production-api",
            "program": "http",
            "index": 1,
            "target_path": "/api/v1",
            "allow_path_override": true
          }'
        ```
      
    

    

    **Result:** `production-api.node-us.containers.hoody.icu`

    **Verify it works:**
    ```bash
    curl https://production-api.node-us.containers.hoody.icu
    # Should return your service response
    ```
  
  
    **At your DNS provider** (Cloudflare, Route53, Namecheap, etc.):
    
    ```
    Type:  CNAME
    Name:  api
    Value: production-api.node-us.containers.hoody.icu
    TTL:   Auto (or 3600)
    ```
    
    **This creates:**
    ```
    api.mycompany.com → production-api.node-us.containers.hoody.icu
    ```
    
    
    Use a short TTL (like 300 seconds) initially so you can fix mistakes quickly. Increase to 3600+ once stable.
    
  
  
    **DNS propagation takes 5-60 minutes.**
    
    **Check propagation:**
    ```bash
    # See if DNS has updated
    dig api.mycompany.com
    
    # Should show:
    # api.mycompany.com. 300 IN CNAME production-api.node-us.containers.hoody.icu.
    ```
    
    **Or use online tools:**
    - https://www.whatsmydns.net
    - Check from multiple locations globally
  
  
    **Hoody automatically detects your CNAME and provisions SSL.**
    
    **When first request arrives:**
    1. Hoody sees `Host: api.mycompany.com`
    2. Recognizes CNAME to our alias
    3. Requests Let's Encrypt certificate
    4. Certificate issued (30-60 seconds)
    5. HTTPS enabled automatically
    
    **First request may take 30-60 seconds** (certificate issuance).
    
    **After that:** Instant HTTPS, automatic renewal every 90 days.
    
    **Test:**
    ```bash
    curl https://api.mycompany.com
    # Should return your service with valid SSL
    ```
  


**Done.** Your custom domain now routes to your container with automatic HTTPS.



---

## The Power of Path Routing

**This is where Hoody aliases unlock something revolutionary:** You can point your domain to a **specific path** in your container, not just the root.

### Why This Changes Everything

**Traditional hosting:**
```
Your domain points to server root only:
api.mycompany.com → /

Problem: Your API is at /api/v1/, but domain points to /
```

**You'd need:**
- Reverse proxy setup (nginx/Apache configuration)
- URL rewrite rules
- Server restarts
- Complex routing logic
- Configuration file management

**With Hoody:**



Then CNAME your domain:
```
api.mycompany.com  CNAME  myapp-api.node-us.containers.hoody.icu
```

**Result:**
```
User requests:  https://api.mycompany.com/users
Proxy routes:   Container's /api/v1/users

No server config. No reverse proxy. Just the alias setting.
```

### Real-World Use Cases

**Use Case 1: Microservices on One Container**

```bash
# One container serves:
# - Frontend at /
# - API at /api/v1
# - Admin panel at /admin

# Create 3 aliases, each targeting different path
POST /api/v1/proxy/aliases
{ "container_id": "CONTAINER_ID", "alias": "app-frontend", "program": "http", "index": 1, "target_path": "/", "allow_path_override": false }

POST /api/v1/proxy/aliases
{ "container_id": "CONTAINER_ID", "alias": "app-api", "program": "http", "index": 1, "target_path": "/api/v1", "allow_path_override": false }

POST /api/v1/proxy/aliases
{ "container_id": "CONTAINER_ID", "alias": "app-admin", "program": "http", "index": 1, "target_path": "/admin", "allow_path_override": false }

# Point 3 domains to same container
www.mycompany.com    CNAME  app-frontend.node-us.containers.hoody.icu
api.mycompany.com    CNAME  app-api.node-us.containers.hoody.icu
admin.mycompany.com  CNAME  app-admin.node-us.containers.hoody.icu
```

**Routing:**
- `www.mycompany.com/about` → Container's `/about`
- `api.mycompany.com/users` → Container's `/api/v1/users`
- `admin.mycompany.com/dashboard` → Container's `/admin/dashboard`

**One container. Three domains. Three isolated path spaces. Zero nginx.**

**Use Case 2: API Versioning**

```bash
# Container serves both v1 and v2 at different paths:
# /api/v1/*
# /api/v2/*

# Create version-specific aliases
POST /api/v1/proxy/aliases
{ "alias": "api-v1", "target_path": "/api/v1", "allow_path_override": false }

POST /api/v1/proxy/aliases
{ "alias": "api-v2", "target_path": "/api/v2", "allow_path_override": false }

# Point domains
v1.api.mycompany.com  CNAME  api-v1.node-us.containers.hoody.icu
v2.api.mycompany.com  CNAME  api-v2.node-us.containers.hoody.icu
```

**Users call:**
- `v1.api.mycompany.com/endpoint` → `/api/v1/endpoint`
- `v2.api.mycompany.com/endpoint` → `/api/v2/endpoint`

**Same container, both versions live, clean domain structure.**

**Use Case 3: Multi-Tenant SaaS**

```bash
# Container organized by tenant:
# /tenant/acme/*
# /tenant/globex/*
# /tenant/initech/*

# Alias per customer
POST /api/v1/proxy/aliases
{ "alias": "acme", "target_path": "/tenant/acme", "allow_path_override": false }

POST /api/v1/proxy/aliases
{ "alias": "globex", "target_path": "/tenant/globex", "allow_path_override": false }

# Customer domains
acme.myapp.com    CNAME  acme.node-us.containers.hoody.icu
globex.myapp.com  CNAME  globex.node-us.containers.hoody.icu
```

**Each customer gets their own domain, routing to their tenant path. Single container serves all tenants.**

### Why This Is Superior

**Traditional routing (nginx/Apache):**
```nginx
# Write config file
server {
  server_name api.mycompany.com;
  location / {
    proxy_pass http://localhost:3000/api/v1;
    rewrite rules...
    header manipulation...
  }
}

# Test config
nginx -t

# Restart server (downtime risk)
systemctl restart nginx

# Hope production didn't break
```

**Hoody routing (one API call):**


  
    ```bash
    # Create alias with path routing — done, live immediately
    hoody proxy create --container-id $CONTAINER_ID \
      --alias my-api --program http --index 1 --target-path /api/v1
    ```
  
  
    ```typescript
    // One call. Live immediately. No restart.
    await client.api.proxyAliases.create({
      container_id: CONTAINER_ID,
      alias: 'my-api',
      program: 'http',
      index: 1,
      target_path: '/api/v1'
    });
    ```
  
  
    ```bash
    curl -X POST "https://api.hoody.icu/api/v1/proxy/aliases" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "container_id": "'$CONTAINER_ID'",
        "alias": "my-api",
        "program": "http",
        "target_path": "/api/v1"
      }'
    ```
  




Done. No restart. No downtime. Live immediately.

---

## Root Domain Setup (Advanced)

**Root domains** (like `mycompany.com` without a subdomain) require different configuration because CNAME records aren't allowed at the DNS root by RFC standards.

### Option 1: ALIAS/ANAME Records (Recommended)

**Some DNS providers support ALIAS or ANAME records** (CloudFlare, DNSimple, Route53):

```
Type:  ALIAS (or ANAME)
Name:  @ (or mycompany.com)
Value: production-api.node-us.containers.hoody.icu
```

**This works like CNAME** but is allowed at the root. Check if your DNS provider supports it.

### Option 2: Subdomain Instead

**The easier solution:** Use `www.mycompany.com` or `app.mycompany.com`:

```
Type:  CNAME
Name:  www
Value: production-api.node-us.containers.hoody.icu
```

Then add a redirect from root to subdomain at your DNS provider.


**Root domains are complex.** Unless you specifically need `mycompany.com` (not `www.mycompany.com`), use a subdomain. It's simpler, more flexible, and works with all DNS providers.


---

## Multiple Domains for One Container

**Point multiple domains to the same alias:**

```bash
# 1. Create one alias
POST /api/v1/proxy/aliases
{ "alias": "prod-api", "program": "http" }

# 2. CNAME multiple domains to it
api.mycompany.com       CNAME  prod-api.node-us.containers.hoody.icu
api.mybrand.com         CNAME  prod-api.node-us.containers.hoody.icu
api-v2.oldcompany.com   CNAME  prod-api.node-us.containers.hoody.icu
```

**All three domains route to the same container service.** Hoody provisions SSL for each domain automatically.

**Use cases:**
- Multiple brand domains pointing to same backend
- API versioning (api-v1.com, api-v2.com)
- Regional domains (api.mycompany.eu, api.mycompany.com)

---

## Domain Migration

### Migrating from Another Platform

**Move an existing domain to Hoody with zero downtime:**


  
    ```bash
    # Deploy your app to Hoody container
    # Create alias
    POST /api/v1/proxy/aliases
    { "alias": "myapp-prod", "program": "http" }
    
    # Test via alias URL first
    curl https://myapp-prod.node-us.containers.hoody.icu
    # Verify everything works
    ```
  
  
    ```
    # Add temporary test subdomain
    test.mycompany.com  CNAME  myapp-prod.node-us.containers.hoody.icu
    
    # Verify SSL provisioning works
    curl https://test.mycompany.com
    # Wait for certificate (30-60 seconds first request)
    ```
  
  
    ```
    # When ready, update production CNAME
    api.mycompany.com  CNAME  myapp-prod.node-us.containers.hoody.icu
    
    # Old:
    # api.mycompany.com  A  203.0.113.50 (old server)
    
    # New:
    # api.mycompany.com  CNAME  myapp-prod.node-us.containers.hoody.icu
    ```
  
  
    ```bash
    # Watch DNS propagation
    watch -n 5 "dig api.mycompany.com | grep CNAME"
    
    # Monitor traffic on new container
    # Check logs in container's terminal
    ```
  


**Downtime:** Minimal (DNS TTL period, usually 5 minutes or less)

### Switching Between Containers

**Change which container a domain points to:**

**Option A: Recreate the alias under the same name** (points to different container)

The `container_id` of an existing alias is immutable—`PATCH` only updates `program`, `index`, `target_path`, `allow_path_override`, `expires_at`, `enabled`, and the alias `name`. To repoint to a different container, delete the alias and recreate it with the **same alias name**. The CNAME target is unchanged, so no DNS edit is required.


  
    ```bash
    # Instant switch — delete + recreate under the same alias name
    hoody proxy delete $ALIAS_ID
    hoody proxy create --container-id $NEW_CONTAINER_ID \
      --alias production-api --program http --index 1
    ```
  
  
    ```typescript
    // Instant switch — DNS unchanged, same alias name on the new container
    await client.api.proxyAliases.delete(ALIAS_ID);
    await client.api.proxyAliases.create({
      container_id: NEW_CONTAINER_ID,
      alias: 'production-api',
      program: 'http',
      index: 1
    });
    ```
  
  
    ```bash
    curl -X DELETE "https://api.hoody.icu/api/v1/proxy/aliases/$ALIAS_ID" \
      -H "Authorization: Bearer $TOKEN"

    curl -X POST "https://api.hoody.icu/api/v1/proxy/aliases" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"container_id": "'$NEW_CONTAINER_ID'", "alias": "production-api", "program": "http", "index": 1}'
    ```
  




**DNS unchanged.** Reusing the same alias name keeps the CNAME target valid, so the domain starts routing to the new container immediately.

**Option B: Create new alias, update CNAME**


  
    ```bash
    # Create new alias for the new container
    hoody proxy create --container-id $NEW_CONTAINER_ID --alias myapp-v2 --program http --index 1
    ```
  
  
    ```typescript
    await client.api.proxyAliases.create({
      alias: 'myapp-v2',
      container_id: NEW_CONTAINER_ID,
      program: 'http',
      index: 1
    });
    ```
  
  
    ```bash
    curl -X POST "https://api.hoody.icu/api/v1/proxy/aliases" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"alias": "myapp-v2", "container_id": "'$NEW_CONTAINER_ID'", "program": "http", "index": 1}'
    ```
  




Then update DNS:
```
api.mycompany.com  CNAME  myapp-v2.node-us.containers.hoody.icu
```

**DNS change required.** Propagation delay (5-60 minutes).

**Recommendation:** Use Option A (recreate under the same name) for instant switching.

---

## SSL Certificate Management

### Automatic Provisioning

**Hoody handles SSL completely:**

1. **Detection:** Proxy sees request for your custom domain
2. **Challenge:** Hoody responds to the ACME HTTP-01 challenge automatically
3. **Issuance:** Certificate issued by Let's Encrypt (30-60 seconds). If Let's Encrypt is rate-limited, Hoody automatically falls back to ZeroSSL.
4. **Installation:** Certificate installed and activated
5. **Renewal:** Auto-renewed before expiry

**You never touch certificates.** It's automatic.

### Certificate Details

**What you get:**
- **Certificate Authority:** Let's Encrypt (primary), with automatic fallback to ZeroSSL when Let's Encrypt rate limits are hit
- **Validation Method:** ACME HTTP-01 challenge (automatic)
- **Certificate Type:** Domain Validation (DV)
- **Validity:** 90 days (auto-renews before expiry)
- **Coverage:** Your exact domain (e.g., `api.mycompany.com`)

**HTTPS enforcement:**
- All HTTP requests → Automatic redirect to HTTPS
- HSTS headers included (tells browsers to always use HTTPS)

### Wildcard Certificates

**For wildcard subdomains** (`*.api.mycompany.com`):


Wildcard certificates require DNS-01 challenge validation, which currently requires manual DNS TXT record updates. Contact support if you need wildcard certificate support.


---

## DNS Provider Examples

### Cloudflare

```
Type:  CNAME
Name:  api
Value: myapp-prod.node-us.containers.hoody.icu
Proxy: ⚠️ OFF (DNS only, not proxied through Cloudflare)
TTL:   Auto
```

**Important:** Turn OFF Cloudflare's proxy (orange cloud icon) to ensure traffic reaches Hoody directly.

### AWS Route53

```
Type:  CNAME
Name:  api.mycompany.com
Value: myapp-prod.node-us.containers.hoody.icu
TTL:   300
Routing Policy: Simple
```

### Google Domains

```
Type:  CNAME
Host:  api
Data:  myapp-prod.node-us.containers.hoody.icu
TTL:   1h
```

### Namecheap

```
Type:          CNAME Record
Host:          api
Value:         myapp-prod.node-us.containers.hoody.icu
TTL:           Automatic
```

---

## Multi-Domain Strategies

### Scenario 1: API + Dashboard on Same Container

**One container serving multiple interfaces:**

```bash
# Create two aliases for different paths
POST /api/v1/proxy/aliases
{
  "alias": "api-backend",
  "program": "http",
  "target_path": "/api/v1",
  "allow_path_override": false
}

POST /api/v1/proxy/aliases
{
  "alias": "admin-dashboard",
  "program": "http",
  "target_path": "/admin",
  "allow_path_override": false
}

# CNAME different domains
api.mycompany.com      CNAME  api-backend.node-us.containers.hoody.icu
admin.mycompany.com    CNAME  admin-dashboard.node-us.containers.hoody.icu
```

**Result:**
- `api.mycompany.com` → Container's `/api/v1/*` only
- `admin.mycompany.com` → Container's `/admin/*` only
- Same container, different domain access, isolated paths

### Scenario 2: Multi-Container Application

**Different containers for frontend/backend:**

```bash
# Frontend container alias
POST /api/v1/proxy/aliases
{ "alias": "frontend", "container_id": "FRONTEND_ID", "program": "http" }

# Backend container alias
POST /api/v1/proxy/aliases
{ "alias": "backend", "container_id": "BACKEND_ID", "program": "http" }

# DNS configuration
www.mycompany.com   CNAME  frontend.node-us.containers.hoody.icu
api.mycompany.com   CNAME  backend.node-us.containers.hoody.icu
```

**Each domain routes to a different container.**

### Scenario 3: Geographic Distribution

**Same application, different regions:**

```bash
# US container
POST /api/v1/proxy/aliases
{ "alias": "app-us", "container_id": "US_CONTAINER", "program": "http" }

# EU container  
POST /api/v1/proxy/aliases
{ "alias": "app-eu", "container_id": "EU_CONTAINER", "program": "http" }

# DNS with GeoDNS routing
api.mycompany.com  →  (US users) → app-us.node-us.containers.hoody.icu
api.mycompany.com  →  (EU users) → app-eu.node-eu.containers.hoody.icu
```

**Use your DNS provider's GeoDNS feature** to route users to nearest container.

---

## Deployment Patterns

### Blue-Green Deployment

**Zero-downtime deployments via DNS switching:**

```bash
# Blue (current production)
POST /api/v1/proxy/aliases
{ "alias": "blue", "container_id": "CURRENT_CONTAINER", "program": "http", "index": 1 }

# Deploy to green (new version)
POST /api/v1/projects/{project_id}/containers
{ "name": "green", ... }

# Create green alias
POST /api/v1/proxy/aliases
{ "alias": "green", "container_id": "NEW_CONTAINER", "program": "http", "index": 1 }

# Test green environment
curl https://green.node-us.containers.hoody.icu

# Switch production (update CNAME)
api.mycompany.com  CNAME  green.node-us.containers.hoody.icu
# (was: blue.node-us.containers.hoody.icu)

# After DNS propagation (5-10 min), all traffic on new version

# Keep blue for rollback
# If issues: Revert CNAME back to blue.node-us.containers.hoody.icu
```

### Canary Deployment

**Use DNS weighting** (if your provider supports it):

```
api.mycompany.com  CNAME  stable.node-us.containers.hoody.icu  (Weight: 90%)
api.mycompany.com  CNAME  canary.node-us.containers.hoody.icu  (Weight: 10%)
```

**10% of users get the canary version.** Monitor, then gradually shift weight.

---

## SSL Certificate Verification

### Check Certificate Status

**After CNAME is configured:**

```bash
# Check SSL certificate
openssl s_client -showcerts -connect api.mycompany.com:443 -servername api.mycompany.com

# Should show:
# issuer=C = US, O = Let's Encrypt, CN = R3
# subject=CN = api.mycompany.com
```

**Or via browser:**
1. Visit `https://api.mycompany.com`
2. Click padlock icon
3. View certificate details
4. Verify: Issued by Let's Encrypt, Valid for your domain

### Certificate Renewal

**Completely automatic:**

- Hoody checks certificate expiration daily
- At 60 days remaining (out of 90): renewal triggered
- New certificate issued and installed automatically
- No downtime, no intervention needed

**You'll never think about certificates again.**

---

## Useful Questions

### Do I need to create a proxy alias before connecting my domain?

**Yes, always.** Custom domains point to proxy aliases via CNAME. The workflow: Create alias → Get alias URL → CNAME your domain to alias URL. You cannot CNAME directly to cryptographic container URLs.

### How long does DNS propagation take?

Typically **5-60 minutes** globally. Your DNS provider's TTL setting affects this. A 300-second TTL means changes propagate in ~5 minutes. A 3600-second TTL means ~60 minutes. Use online tools like whatsmydns.net to check global propagation.

### Is SSL automatic for custom domains?

Yes. When Hoody's proxy detects a CNAME pointing to an alias, it automatically requests a Let's Encrypt certificate for your custom domain. The first HTTPS request may take 30-60 seconds (certificate issuance time), then it's instant and auto-renews every 90 days.

### Can I use my root domain (mycompany.com) not just subdomains?

Root domains require ALIAS/ANAME records (not supported by all DNS providers) or A records (which require static IPs). **Recommendation:** Use subdomains (`www.mycompany.com`, `app.mycompany.com`) with CNAME records—simpler, more flexible, works everywhere.

### What happens if my CNAME points to a deleted alias?

The domain will return DNS errors (NXDOMAIN) because the target doesn't exist. Always verify the alias exists before updating DNS, and avoid deleting aliases that have active CNAMEs pointing to them.

### Can multiple custom domains point to the same container?

Yes. Create one alias, then CNAME multiple domains to it. Hoody provisions separate SSL certificates for each domain. Common use case: `www.mycompany.com` and `app.mycompany.com` both pointing to the same HTTP service.

### Do I need to configure anything in the container for custom domains to work?

No container configuration needed. Your application just binds to a port (e.g., 3000) and the proxy handles all routing, SSL, and domain resolution automatically. The app itself doesn't know about domains—it just responds to HTTP requests.

### Can I use Cloudflare's proxy (orange cloud) with Hoody?

**Turn it OFF.** Cloudflare's proxy interferes with Hoody's SSL provisioning and IP preservation. Use DNS-only mode (gray cloud). Your traffic goes: Client → Hoody Proxy → Container, not through Cloudflare's edge network.

### How do I switch a domain from one container to another?

**Option A (instant):** The alias `container_id` is immutable, so delete the alias and recreate it with the **same name** on the new container (`DELETE` then `POST /api/v1/proxy/aliases`)—the CNAME target is unchanged, so no DNS edit is needed. **Option B (slower):** Create a new alias pointing to the new container, then update CNAME to point to the new alias (requires DNS propagation).

### What's the maximum number of custom domains I can connect?

No limit. Each alias can support unlimited CNAMEs (at your DNS provider level). One Hoody alias can have dozens of custom domains pointing to it—each gets automatic SSL and routes to the same container service.

---

## Troubleshooting

### CNAME Not Working

**1. Verify CNAME is correct**

```bash
dig api.mycompany.com

# Should show CNAME record pointing to alias.node-us.containers.hoody.icu
# If showing A record or different CNAME: DNS not updated yet
```

**2. Check alias exists and is enabled**



Verify:
- Alias exists
- enabled: true
- container is running

**3. Test alias URL directly**

```bash
# Bypass custom domain, test alias
curl https://myapp-prod.node-us.containers.hoody.icu

# If this works but custom domain doesn't:
# → DNS propagation still in progress
# → Wait 15-30 more minutes
```

### SSL Certificate Not Provisioning

**Common causes:**

1. **CNAME pointing to wrong target**
   ```bash
   # Wrong: CNAME to cryptographic URL
   api.mycompany.com  CNAME  67e89abc...node-us.containers.hoody.icu ❌
   
   # Correct: CNAME to alias
   api.mycompany.com  CNAME  myapp-prod.node-us.containers.hoody.icu ✅
   ```

2. **DNS not fully propagated**
   - Let's Encrypt validation fails if DNS not worldwide
   - Wait for full propagation (up to 60 minutes)

3. **Cloudflare proxy enabled**
   - Orange cloud icon in Cloudflare = Proxied through CF
   - Must be gray cloud (DNS only) for Hoody SSL

4. **Port 80 blocked**
   - Let's Encrypt uses HTTP-01 challenge on port 80
   - Ensure firewall allows port 80 temporarily

**Check Hoody status:**



Contact support if certificate persistently fails.

5. **ACME rate limits exceeded**
   - Let's Encrypt enforces per-registered-domain rate limits (for example, the duplicate-certificate limit of 5 per week for the same exact set of names)
   - If you've been testing extensively with the same domain, you may hit one of these limits
   - **Built-in mitigation:** When Let's Encrypt is rate-limited, Hoody automatically falls back to ZeroSSL — so a Let's Encrypt limit usually does not block issuance outright
   - **If both providers are exhausted:** Wait for the weekly reset, or use a different subdomain
   - **Prevention:** Use different subdomains for testing (test1.example.com, test2.example.com) instead of repeatedly recreating certificates for the same domain

**Check if you hit rate limits:**
```bash
# Visit Let's Encrypt rate limit checker
# https://crt.sh/?q=%.mycompany.com

# Shows all certificates issued for your domain
# If you see many recent certificates: likely hit the limit
```

**Workaround while waiting:**
- Use a different subdomain temporarily
- Or use the alias URL directly (already has SSL)
- Rate limit resets 7 days after first certificate in the batch

### DNS Propagation Delays

**DNS changes take time:**

| Provider | Typical TTL | Max Wait |
|----------|-------------|----------|
| Cloudflare | 5 minutes | 10 minutes |
| Route53 | 5 minutes | 15 minutes |
| Google Domains | 1 hour | 2 hours |
| Namecheap | 30 minutes | 1 hour |
| GoDaddy | 1 hour | 2 hours |

**Check propagation:**
```bash
# From your machine
dig api.mycompany.com @8.8.8.8

# From different DNS server
dig api.mycompany.com @1.1.1.1

# If different results: Still propagating
```

---

## Best Practices

### 1. Test Before Production

**Always test via alias URL before adding custom domain:**

```bash
# 1. Create alias
POST /api/v1/proxy/aliases
{ "alias": "myapp-test", ... }

# 2. Test thoroughly
curl https://myapp-test.node-us.containers.hoody.icu
# Run full test suite, verify responses

# 3. Add custom domain only when alias works perfectly
api.mycompany.com  CNAME  myapp-test.node-us.containers.hoody.icu
```

### 2. Use Descriptive Aliases

**Alias names should indicate purpose:**

```
✅ production-api
✅ staging-frontend
✅ blue-deployment
✅ myapp-v2

❌ app
❌ test
❌ api
❌ x
```

**Why:** When you have 20 domains, clear aliases prevent confusion.

### 3. Document CNAME Targets

**Track which domain points where:**

```yaml
# domains.yml
domains:
  api.mycompany.com:
    cname_target: production-api.node-us.containers.hoody.icu
    alias_id: 63a3e4b5c6d7e8f9a0b1c2d3
    container_id: 890abcdef12345678901cdef
    
  staging.mycompany.com:
    cname_target: staging-api.node-us.containers.hoody.icu
    alias_id: 74b4f5c6d7e8f9a0b1c2d3e4
    container_id: 901bcdef12345678901cdefa
```

**Prevents:** "Which alias does api.mycompany.com point to again?"

### 4. Set Alerts for Expiration

**If you use expiring aliases:**

```bash
POST /api/v1/proxy/aliases
{
  "alias": "beta-program",
  "expires_at": "2026-08-16T00:00:00.000Z"  # Absolute ISO 8601 timestamp
}
```

**Set calendar reminders** 7 days before expiration if users depend on this URL.

---

## Your Brand, Our Infrastructure

**The power of custom domains:**

```
Your branding:
https://api.acme.com
https://app.techstartup.io
https://platform.saas.com

Hoody infrastructure:
https://prod-acme.node-us.containers.hoody.icu
https://startup-app.node-eu.containers.hoody.icu
https://saas-platform.node-asia.containers.hoody.icu
```

**Users see your brand. Hoody handles the infrastructure.**

**Zero certificate management. Zero SSL renewal. Zero proxy configuration.**

Just a CNAME. That's it.

---

## Quick Reference

### Complete Setup Checklist

- [ ] Create container with hoody-kit enabled
- [ ] Verify container is running (`GET /api/v1/containers/{id}`)
- [ ] Create proxy alias (`POST /api/v1/proxy/aliases`)
- [ ] Test alias URL (` curl https://alias.node-us.containers.hoody.icu`)
- [ ] Add CNAME record at DNS provider
- [ ] Wait for DNS propagation (5-60 minutes)
- [ ] Test custom domain (`curl https://api.mycompany.com`)
- [ ] Verify SSL certificate (browser padlock icon)
- [ ] Configure [permissions](./permissions/) if needed

### DNS Record Format

```
Type:  CNAME
Name:  [subdomain]
Value: [alias].[serverName].containers.hoody.icu
TTL:   300-3600 (lower = faster updates, higher = better caching)
```

**Example:**
```
Type:  CNAME
Name:  api
Value: prod-api.node-us.containers.hoody.icu
TTL:   3600
```

---

## What's Next

**Secure your domains:**
- **[Configure Permissions →](./permissions/)** - Add authentication to custom domains

**Explore related topics:**
- **[Proxy Overview →](./)** - Understanding the overall proxy architecture
- **[Aliases →](./aliases/)** - Deep dive into alias management

---

> **Your domain. Hoody's infrastructure.**  
> **CNAME record. Automatic SSL.**  
> **Zero certificate management. Zero downtime deployments.**

**Professional URLs backed by containerized power.**