# How to Update Cloudflare Tunnel with New Subdomains

This guide documents the process for adding new subdomains to your existing Cloudflare Tunnel setup.

## Overview

Your Cloudflare Tunnel is already configured and running. Adding a new subdomain requires:
1. Creating a DNS CNAME record in Cloudflare
2. Updating the local cloudflared configuration
3. Restarting the tunnel container

## Current Setup

- **Tunnel ID**: `c8be17f4-8314-4020-a777-966f08a10fc2`
- **Account ID**: `71d04f6674064cf7b5ca82d12a2fdf12`
- **Zone ID**: `0a0f40b97a632c7be6827793cc73fce7`
- **Domain**: `leebasehome.com`
- **Tunnel Endpoint**: `c8be17f4-8314-4020-a777-966f08a10fc2.cfargotunnel.com`

### Current Subdomains
- `nginx.leebasehome.com` → `http://host.docker.internal:86` (nginx container)
- `chat.leebasehome.com` → `http://host.docker.internal:3000` (Open WebUI container)

## Prerequisites

- Cloudflare API token stored in `cf-api-token.txt`
- Docker container running on a specific port
- Existing cloudflared tunnel configuration at `~/.cloudflared/`

## Step-by-Step Process

### Step 1: Create DNS CNAME Record

You have two options: API or Manual.

#### Option A: Using Cloudflare API (Recommended)

```bash
# Set the API token
CF_API_TOKEN=$(cat cf-api-token.txt)

# Set your variables
ZONE_ID="0a0f40b97a632c7be6827793cc73fce7"
SUBDOMAIN="chat"  # Change this for your subdomain
TUNNEL_ENDPOINT="c8be17f4-8314-4020-a777-966f08a10fc2.cfargotunnel.com"

# Create the CNAME record
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "type": "CNAME",
    "name": "'"$SUBDOMAIN"'",
    "content": "'"$TUNNEL_ENDPOINT"'",
    "proxied": true,
    "ttl": 1
  }'
```

**Note**: If you get a "No route for that URI" error, your API token may have limited permissions. Use the manual method instead.

#### Option B: Manual via Cloudflare Dashboard

1. Go to [Cloudflare Dashboard](https://dash.cloudflare.com/)
2. Select your domain (`leebasehome.com`)
3. Navigate to **DNS** → **Records**
4. Click **Add record**
5. Configure:
   - **Type**: `CNAME`
   - **Name**: Your subdomain (e.g., `chat`)
   - **Target**: `c8be17f4-8314-4020-a777-966f08a10fc2.cfargotunnel.com`
   - **Proxy status**: Proxied (orange cloud)
   - **TTL**: Auto
6. Click **Save**

### Step 2: Update Cloudflared Configuration

Edit `~/.cloudflared/config.yml` and add your new hostname to the `ingress` section:

```bash
# Open the config file
nano ~/.cloudflared/config.yml
```

Add your new hostname entry **before** the catch-all `http_status:404` rule:

```yaml
tunnel: c8be17f4-8314-4020-a777-966f08a10fc2
credentials-file: /home/nonroot/.cloudflared/c8be17f4-8314-4020-a777-966f08a10fc2.json

ingress:
  - hostname: nginx.leebasehome.com
    service: http://host.docker.internal:86
  - hostname: chat.leebasehome.com
    service: http://host.docker.internal:3000
  # Add your new subdomain here:
  - hostname: newsubdomain.leebasehome.com
    service: http://host.docker.internal:PORT
  # This catch-all rule must always be last:
  - service: http_status:404
```

**Important**: Replace `newsubdomain` with your subdomain name and `PORT` with your container's port number.

### Step 3: Restart Cloudflared Container

```bash
# Restart the tunnel container to apply changes
docker restart cloudflared-tunnel

# Wait a few seconds, then check logs
sleep 3
docker logs --tail 20 cloudflared-tunnel
```

Look for these success indicators:
- `Starting tunnel tunnelID=c8be17f4-8314-4020-a777-966f08a10fc2`
- `Registered tunnel connection` (should see 4 connections)
- No error messages

### Step 4: Verify the Subdomain

Test your new subdomain:

```bash
# Check DNS resolution
curl -I https://newsubdomain.leebasehome.com

# Or visit in browser
# https://newsubdomain.leebasehome.com
```

You should see:
- HTTP/2 200 (or appropriate response from your service)
- `server: cloudflare` header
- Your application's response

## Quick Reference Commands

```bash
# View current config
cat ~/.cloudflared/config.yml

# Check running containers
docker ps | grep cloudflared

# View tunnel logs
docker logs -f cloudflared-tunnel

# Restart tunnel
docker restart cloudflared-tunnel

# Test subdomain
curl -I https://subdomain.leebasehome.com
```

## Troubleshooting

### DNS Not Resolving
- Wait 1-2 minutes for DNS propagation
- Verify CNAME record exists in Cloudflare dashboard
- Check that record points to correct tunnel endpoint

### 502/504 Errors
- Verify container is running: `docker ps`
- Check container port is correct in config.yml
- Ensure `host.docker.internal` is accessible from cloudflared container
- Review cloudflared logs: `docker logs cloudflared-tunnel`

### Configuration Not Applied
- Ensure you saved config.yml changes
- Verify YAML syntax (indentation must be exact)
- Restart cloudflared container
- Check for error messages in logs

### Tunnel Not Starting
- Check tunnel credentials file exists: `ls ~/.cloudflared/*.json`
- Verify Docker container has proper volume mount
- Review full logs: `docker logs cloudflared-tunnel`

## Example: Adding a New Subdomain

Let's say you want to add `api.leebasehome.com` pointing to a service on port 8080:

```bash
# 1. Create DNS record (manual or API)
# Via API:
CF_API_TOKEN=$(cat warp-cf-token.txt)
curl -X POST "https://api.cloudflare.com/client/v4/zones/0a0f40b97a632c7be6827793cc73fce7/dns_records" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "type": "CNAME",
    "name": "api",
    "content": "c8be17f4-8314-4020-a777-966f08a10fc2.cfargotunnel.com",
    "proxied": true
  }'

# 2. Edit config
nano ~/.cloudflared/config.yml
# Add this line before the catch-all:
#   - hostname: api.leebasehome.com
#     service: http://host.docker.internal:8080

# 3. Restart tunnel
docker restart cloudflared-tunnel

# 4. Test
curl -I https://api.leebasehome.com
```

## Additional Resources

- [Cloudflare Tunnel Documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/)
- [Cloudflare API Documentation](https://developers.cloudflare.com/api/)
- [Docker Networking Guide](https://docs.docker.com/network/)

## Notes

- Always keep the catch-all `http_status:404` rule as the last entry in ingress
- The `host.docker.internal` hostname works because cloudflared container uses `--add-host host.docker.internal:host-gateway`
- Cloudflare Tunnel supports multiple protocols: http://, https://, tcp://, unix://, etc.
- DNS records are proxied through Cloudflare for DDoS protection and caching

---

*Last Updated: January 25, 2026*
*Tunnel Created: January 24, 2026*
