sitemap.mjs was a step I ran by hand, so the moment I rebuilt without it the file vanished from dist and the deploy shipped a site with no sitemap — on a site whose entire point is being findable. Nothing caught it because nothing was looking. It is now inside `pnpm build`, CI asserts the file exists, and deploy.sh smoke-tests /sitemap.xml, /robots.txt and an OG card against the live hostname. The 404 assertion was also a warning rather than a failure; it exits now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019mt6sHQHEnEYrJZvoMCJSB
Deploying
Static build, rsynced to cloud-2, served by Caddy.
pnpm build && bash deploy/deploy.sh
The pieces
| Host | cloud-2, ubuntu@100.92.185.76 (tailnet only) |
| Root | /var/www/demo.primeintellectgrowth.com |
| Snapshots | …-rollbacks/, last 10, hard-linked |
| DNS | OCI zone primeintellectgrowth.com → 170.9.14.61, explicit A record, no wildcard |
| Caddy | a block appended to /etc/caddy/Caddyfile |
The trap that costs an afternoon
bind 10.0.0.2 is mandatory in the Caddy block, and its absence is silent.
Without it Caddy builds a second server on *:443 that has never heard of this
hostname. Public traffic — which NATs to 10.0.0.2 — falls through to an empty
200 behind a perfectly valid certificate. Worse, a
curl --resolve demo.primeintellectgrowth.com:443:127.0.0.1 from cloud-2 itself
still passes.
deploy.sh therefore smoke-tests the real public hostname from the deploying
machine and fails on a response under 1 kB.
Do not use PIG's deploy/Caddyfile.example as a template — it omits the bind.
Rolling back
ssh ubuntu@100.92.185.76
ls -1dt /var/www/demo.primeintellectgrowth.com-rollbacks/*/
sudo rsync -a --delete <that-dir>/ /var/www/demo.primeintellectgrowth.com/
No Caddy reload needed; the root path does not change.
Editing the live Caddyfile
Scope the edit to this site's block. Several sites on cloud-2 carry
byte-identical header strings, so a naive global replace hits two of them. Slice
between demo.primeintellectgrowth.com { and the next hostname, and assert the
match is unique inside that slice.