# Adding a New Subdomain

Every new subdomain needs to be registered in three places. Miss one and either
the DNS won't auto-update when your WAN IP changes, or the service won't be reachable.

---

## The Three Places

| # | Where | What it does |
|---|-------|-------------|
| 1 | **Cloudflare DNS** | Creates the A record |
| 2 | **DDNS compose file** | Keeps the A record pointed at your current WAN IP |
| 3 | **NPM proxy host** | Routes HTTPS traffic to the right container |

---

## Step 1 — Cloudflare DNS

Create the A record via the Cloudflare dashboard or API.

**Proxied (orange cloud)** — use for all standard HTTP/HTTPS services:
```bash
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/dns_records" \
  -H "Authorization: Bearer $CF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"A","name":"myservice.vish.gg","content":"1.2.3.4","proxied":true}'
```

**Direct (grey cloud)** — use only for non-HTTP protocols (TURN, SSH, game servers, WebRTC):
```bash
# same but "proxied":false
```

**Zone IDs:**
| Domain | Zone ID |
|--------|---------|
| `vish.gg` | `4dbd15d096d71101b7c0c6362b307a66` |
| `thevish.io` | `11681f1c93ca32f56a0c41973e02b6f9` |
| `crista.love` | *(check Cloudflare dashboard)* |

The content IP doesn't matter much if it's proxied — the DDNS updater will overwrite it.
Use a placeholder like `1.2.3.4` for now.

---

## Step 2 — DDNS Compose File

Add the domain to the correct host's DDNS `DOMAINS=` list. Pick the host whose
WAN IP the service is behind:

| Host | File | Use when |
|------|------|----------|
| Atlantis / Calypso (home) | `hosts/synology/atlantis/dynamicdnsupdater.yaml` | Service is behind home WAN IP |
| concord-nuc | `hosts/physical/concord-nuc/dyndns_updater.yaml` | API/direct-access on concord-nuc |
| Seattle VPS | `hosts/vms/seattle/ddns-updater.yaml` | Service is on the Seattle VPS |
| Guava (crista.love) | `hosts/physical/guava/portainer_yaml/dynamic_dns.yaml` | crista.love subdomains |

For a standard proxied service on Atlantis/Calypso, edit `dynamicdnsupdater.yaml`
and append your domain to the `ddns-vish-proxied` service:

```yaml
- DOMAINS=...,myservice.vish.gg   # add here, keep comma-separated
- PROXIED=true
```

For an unproxied (direct) domain, use the `ddns-thevish-unproxied` service or
create a new service block with `PROXIED=false`.

Then redeploy the stack via Portainer (Atlantis, stack `dyndns-updater-stack`, ID 613):
```bash
# Portainer API — or just use the UI: Stacks → dyndns-updater-stack → Editor → Update
```

---

## Step 3 — NPM Proxy Host

Add a proxy host at **http://npm.vish.gg:81** (or `http://192.168.0.250:81`):

1. **Hosts → Proxy Hosts → Add Proxy Host**
2. **Domain names**: `myservice.vish.gg`
3. **Forward hostname/IP**: container name or LAN IP of the service
4. **Forward port**: the service's internal port
5. **SSL tab**: Request a new Let's Encrypt cert, enable **Force SSL**
6. *(Optional)* **Advanced tab**: add Authentik forward-auth snippet if SSO is needed

---

## Exceptions — services that skip Step 3

If your subdomain doesn't need an NPM proxy rule (direct-access APIs, WebRTC,
services with their own proxy), add it to `DDNS_ONLY_EXCEPTIONS` in
`.gitea/scripts/dns-audit.py` so the daily audit doesn't flag it:

```python
DDNS_ONLY_EXCEPTIONS = {
    ...
    "myservice.vish.gg",  # reason: direct access / own proxy
}
```

---

## Step 4 — Verify

Run the DNS audit to confirm everything is wired up:

```bash
cd /home/homelab/organized/repos/homelab
CF_TOKEN=<your-cf-token> \
NPM_EMAIL=<npm-admin-email> \
NPM_PASSWORD="REDACTED_PASSWORD" \
python3 .gitea/scripts/dns-audit.py
```

The CF token is stored in Portainer as `CLOUDFLARE_API_TOKEN` on the DDNS stacks.
NPM credentials are stored as `NPM_EMAIL` / `NPM_PASSWORD` Gitea Actions secrets.
The audit also runs automatically every day at 08:00 UTC — check the Gitea Actions tab.

Expected output:
```
✅ All N DDNS domains OK, CF and DDNS are in sync
```

---

## Commit the changes

```bash
git add hosts/synology/atlantis/dynamicdnsupdater.yaml   # (whichever file you edited)
git commit -m "Add myservice.vish.gg subdomain"
git push
```

Portainer will pick up the DDNS change on the next git redeploy, or trigger it manually.
