# DNS operations

HexaHost GameCloud stores desired DNS records in PostgreSQL (`server_dns_records`) and synchronizes them through a provider abstraction in `@hexahost/dns`.

## Providers

| Provider | `DNS_PROVIDER` | Use case |
|----------|----------------|----------|
| Local metadata | `local` (default) | Development — records exist only in the database |
| RFC2136 dynamic updates | `rfc2136` | Production with BIND or compatible authoritative DNS |

## Production (RFC2136)

Set on API and worker hosts:

```env
DNS_PROVIDER=rfc2136
GAME_BASE_DOMAIN=play.example.net
EDGE_PUBLIC_HOST=203.0.113.10
EDGE_LISTEN_PORT=25565
RFC2136_SERVER=ns1.internal.example.net
RFC2136_KEY_NAME=gamecloud-updater.
RFC2136_KEY_SECRET=base64-encoded-secret
RFC2136_TTL=300
```

Requirements:

- `nsupdate` (bind9-utils) installed on API/worker hosts
- TSIG key authorized for A and SRV updates on `*.play.example.net`
- Edge gateway reachable at `EDGE_PUBLIC_HOST:EDGE_LISTEN_PORT`

## Record layout

For each Java server with join slug `my-server-abc123`:

- `A` record: `my-server-abc123.play.example.net` → edge gateway IP
- `SRV` record: `_minecraft._tcp.my-server-abc123.play.example.net` → edge hostname/port

## Worker sync

The worker runs a DNS sync tick every 60 seconds (`pushPendingDnsRecords`). Records start as `PENDING` when `DNS_PROVIDER=rfc2136` and move to `ACTIVE` or `FAILED`.

## Troubleshooting

1. Check `server_dns_records.status` and `lastError` in PostgreSQL.
2. Run `nsupdate -y` manually with the generated script from logs.
3. Verify TSIG key name ends with `.` if your nameserver expects FQDN form.
