chore: add missing source modules to version control
Deploy to Production / deploy (push) Failing after 7s

apix-demo, apix-portal/src, apix-spider/src, apix-registry/src,
apix-common/src were never staged. Without them the CI build has no
source to compile and the Docker images cannot be produced.

Also adds docs/ (infrastructure notes) missed in prior commits.

Co-Authored-By: Mira <noreply@anthropic.com>
This commit is contained in:
Carsten Rehfeld
2026-05-14 15:49:03 +02:00
parent a9b3354bde
commit 46f32c2df2
87 changed files with 6657 additions and 34 deletions
+278
View File
@@ -0,0 +1,278 @@
# DNS Migration: IONOS → BunnyDNS
Safe, zero-downtime migration of `api-index.org` from IONOS to BunnyDNS,
enabling apex CNAME support for the Bunny.net CDN.
**Risk profile:** Low if the checklist is followed in order. The domain stays
fully operational at every step. IONOS remains the authoritative fallback
until you explicitly confirm the migration is complete.
---
## Overview
```
Phase 0 — Audit Inventory every record in IONOS. Nothing changes.
Phase 1 — Reduce TTL Lower TTL to 300 s. Wait for old TTL to drain.
Phase 2 — Mirror Replicate all records into BunnyDNS. Verify.
Phase 3 — Nameservers Change NS at IONOS registrar → Bunny.net servers.
Phase 4 — CDN switch Replace A record with CNAME to Bunny.net CDN edge.
Phase 5 — Cleanup Confirm everything. IONOS zone stays intact as archive.
```
**Total calendar time:** 23 days minimum (TTL drain + propagation windows).
You can compress to ~24 h if IONOS allows TTL = 60 s and you monitor closely.
---
## Phase 0 — Audit Existing Records
**Do this before touching anything.**
Log in to IONOS → Domains & SSL → `api-index.org` → DNS.
Export or manually list every record. With no email on the domain the expected
records are minimal:
| Type | Name | Value | Notes |
|------|------|-------|-------|
| A | `@` | VPS IP or IONOS parking IP | Migrate this |
| A / CNAME | `www` | same IP or alias | Migrate this |
| CNAME | `_domainconnect` | IONOS internal | **Do NOT migrate — IONOS-specific** |
No MX, SPF, DKIM, or DMARC records exist (no email = no mail records).
This makes the migration low-risk: there is nothing here that can cause an
hours-long silent failure. The worst case is the website is briefly unreachable,
which resolves as soon as you revert the nameservers.
**Identify the current TTL** for each record. IONOS default is often 3600 s (1 h).
That is the minimum wait time after reducing TTL before the change is globally drained.
---
## Phase 1 — Reduce TTL
Change every record's TTL in IONOS to **300 seconds** (5 minutes).
IONOS UI path: DNS record → Edit → TTL field.
If IONOS does not allow TTL below 3600 on your plan, use 3600 — it just means
a longer wait in Phase 3.
**After saving the reduced TTLs, wait for the old TTL to fully drain.**
If the old TTL was 3600 s (1 h), wait at least 1 hour before proceeding.
This ensures no resolver is caching the old TTL value.
Verify the reduced TTL is live from an external resolver:
```bash
# Should show TTL=300 (or close to it) in the answer section
dig api-index.org A +noall +answer
dig api-index.org MX +noall +answer
```
Do not proceed to Phase 2 until the TTL shown in `dig` output matches your
reduced value.
---
## Phase 2 — Mirror Records into BunnyDNS
### 2a. Create the BunnyDNS zone
1. Log in to Bunny.net → DNS → Add Zone
2. Enter `api-index.org` and confirm
3. Bunny.net assigns two nameservers (e.g. `kiki.bunny.net`, `coco.bunny.net`) —
note these for Phase 3
### 2b. Add every record from Phase 0
Replicate the full record list into BunnyDNS exactly — same name, same value,
same type. Use TTL = 300 for all records during migration.
**Do not add:**
- `_domainconnect` — IONOS-internal, not needed
- IONOS parking/redirect entries — not needed
**Do add:**
- A record `@` → VPS IP
- A record (or CNAME) `www` → VPS IP (or `api-index.org`)
For the apex A record (`@`), add it pointing to the **Hetzner VPS IP** for now.
You will convert it to the CDN CNAME in Phase 4 — not before.
### 2c. Verify the BunnyDNS zone before touching IONOS
Use `dig` with BunnyDNS as the explicit resolver to query the zone before
nameserver delegation. Replace `kiki.bunny.net` with your assigned nameserver:
```bash
# A record — should return VPS IP
dig @kiki.bunny.net api-index.org A +short
# www
dig @kiki.bunny.net www.api-index.org A +short
```
Compare every answer against your Phase 0 audit.
**Do not proceed to Phase 3 until all records match.**
---
## Phase 3 — Switch Nameservers at IONOS
This is the single step that transfers authority. Once saved, resolvers will
gradually start querying BunnyDNS instead of IONOS. IONOS DNS zone remains
intact — you are only changing where resolvers are pointed, not deleting anything.
### 3a. Change nameservers in IONOS
IONOS UI path: Domains & SSL → `api-index.org` → Nameservers → Use custom nameservers
Enter the two nameservers from BunnyDNS (e.g.):
```
kiki.bunny.net
coco.bunny.net
```
Save. IONOS will show a warning that custom nameservers override IONOS DNS — confirm.
### 3b. Wait for propagation
Propagation is complete when global resolvers return the BunnyDNS IP for your domain.
This typically takes 1560 minutes with TTL=300. It can take up to 48 hours in rare
cases (resolvers ignoring low TTLs). Monitor:
```bash
# Repeat every few minutes — watch for the IONOS nameservers to disappear
dig api-index.org NS +short
# Check from multiple global vantage points
# https://dnschecker.org/#A/api-index.org — paste in browser, check all green
```
**During propagation:** Some resolvers still use IONOS, some use BunnyDNS.
Both zones have identical records pointing to the VPS IP — so the site stays up
regardless of which nameserver a resolver hits.
### 3c. Verify after propagation
```bash
# NS records should now show Bunny.net nameservers from all resolvers
dig api-index.org NS +short
# A record resolves to VPS IP
dig api-index.org A +short
# End-to-end HTTPS
curl -sv https://api-index.org/ 2>&1 | grep -E "HTTP|certificate"
```
Do not proceed to Phase 4 until all checks pass.
---
## Phase 4 — Switch Apex Record to CDN CNAME
Only do this after Phase 3 is fully confirmed.
### 4a. Run the Bunny.net CDN setup script
If not already done, provision the pull zone:
```bash
BUNNYNET_API_KEY=your-key \
ORIGIN_URL=https://<vps-ip> \
CUSTOM_HOSTNAME=api-index.org \
SYSLOG_HOST=<vps-ip> \
INSTALL_CRON=true \
./scripts/setup-bunnynet.sh
```
Note the CDN hostname printed at the end (e.g. `apix-registry.b-cdn.net`).
### 4b. Replace the apex A record with a CNAME in BunnyDNS
In BunnyDNS → `api-index.org` zone:
1. Delete the `@` A record pointing to the VPS IP
2. Add a `CNAME` record: `@``apix-registry.b-cdn.net` (your CDN hostname)
BunnyDNS supports CNAME at the apex via automatic flattening — this is why
you migrated here.
### 4c. Verify CDN is serving the domain
```bash
# A record now resolves to Bunny.net edge IP (not VPS IP)
dig api-index.org A +short
# HTTPS still works
curl -sv https://api-index.org/ 2>&1 | grep HTTP
# Second request should be a CDN cache HIT
curl -sI "https://api-index.org/services?capability=nlp" | grep -i cache
```
---
## Phase 5 — Cleanup and Archive
**Do not delete the IONOS DNS zone.** Leave it intact as a ready-to-activate
fallback for at least 30 days. If something goes wrong after Phase 3, you can
revert by changing the nameservers back to IONOS in the registrar — the zone
still has all the correct records.
After 30 days of stable operation:
- IONOS zone can be deleted or left (it costs nothing to keep)
- Document the Bunny.net nameservers in `.env` or `docs/` for future reference
---
## Rollback Procedure
At any phase before Phase 3 is complete: nothing has changed — no rollback needed.
After Phase 3 (nameserver switch):
```
IONOS → Domains → api-index.org → Nameservers → Use IONOS nameservers
```
Propagation back takes 560 minutes with TTL=300.
The IONOS zone was never modified — it still has all records.
After Phase 4 (CNAME switch):
1. In BunnyDNS: delete the CNAME `@`, re-add the A record `@` → VPS IP
2. The CDN is bypassed; traffic flows directly to VPS again
---
## Checklist Summary
```
Phase 0
[ ] Audit and export all records from IONOS (expected: A @ , A/CNAME www, _domainconnect)
[ ] Identify current TTL values
[ ] Confirm no MX records present (no email on domain)
Phase 1
[ ] Reduce all TTLs to 300 s in IONOS
[ ] Wait for old TTL to drain (at minimum the old TTL duration)
[ ] dig confirms TTL ~300 in answers
Phase 2
[ ] BunnyDNS zone created for api-index.org
[ ] A record @ and www replicated into BunnyDNS (no MX/TXT to worry about)
[ ] Verified via: dig @<bunny-ns> api-index.org A and dig @<bunny-ns> www.api-index.org A
Phase 3
[ ] Nameservers changed at IONOS registrar to BunnyDNS
[ ] Propagation monitored until global NS shows Bunny.net
[ ] HTTPS end-to-end test passes
Phase 4
[ ] CDN pull zone provisioned (setup-bunnynet.sh)
[ ] Apex A record replaced with CNAME in BunnyDNS
[ ] CDN cache HIT confirmed on second request
Phase 5
[ ] IONOS zone archived (do not delete for 30 days)
[ ] Bunny.net nameservers documented
```