| 1 | # DDNS cutover |
| 2 | |
| 3 | The `.test` VM does not run DDNS. Evaluating `service/ddns-updater/service.pkl` on the VM with `domain=paperclover.net` produced valid JSON for the Cloudflare `*.paperclover.net` record and required `cloudflare_zone_id` and `cloudflare_api_token`. Zenith's legacy `.env` contains the corresponding `CLOUDFLARE_ZONE_ID` and `CLOUDFLARE_API_TOKEN` keys. No public DNS record was changed during this check. |
| 4 | |
| 5 | The current worktree's `config/`, `service/`, and `tools/` generated 27 production-domain jobs, all accepted by `nomad job validate` on the VM. This was validation only; it did not submit jobs or contact Cloudflare. |
| 6 | |
| 7 | Snow Globe replaces a service hostname's first label with its stage ID: Shale becomes `shale-preview-12345678.paperclover.net`, while evil.inc Forgejo becomes `evil-forgejo-preview-12345678.evil.paperclover.net`. Cloudflare's wildcard DNS records [cover multiple levels when no specific record takes precedence](https://developers.cloudflare.com/dns/manage-dns-records/reference/wildcard-dns-records/). Read-only DNS queries resolved both a sample Shale stage name and an otherwise nonexistent name under `evil.paperclover.net` to the current public address. The README's `.staging.paperclover.net` example describes a different hostname scheme from the current CLI. No public record changed; ACME issuance still needs a live cutover check. |
| 8 | |
| 9 | At production cutover, set `STUDIO_DEPLOY_HOST` and `STUDIO_DEPLOY_PORT` for the new host, then run `bash tools/import-legacy-secrets.sh ddns-updater CLOUDFLARE_ZONE_ID CLOUDFLARE_API_TOKEN`. The order matches the required secret fields in the service definition. Start the Snow Globe DDNS job only after the old updater is stopped; otherwise both updaters can write the wildcard record. Verify the provider status and the public record after the new job starts. |