Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
Commitfe8ae12

fix(deploy): repoint docs from obsolete Vultr 45.76.171.37 to Hetzner Gluecron-1 178.104.208.252

fix(deploy): repoint docs from obsolete Vultr 45.76.171.37 to Hetzner Gluecron-1 178.104.208.252

Prior commits assumed the deploy target was the Vultr bare-metal box at
45.76.171.37 — that's the OLD home and is now serving stale content (per
Craig's "obsolete server" report). The real prod box is the Hetzner
Cloud server "Gluecron-1" at 178.104.208.252 (Falkenstein, eu-central),
created 4 days ago and ready to receive the first deploy.

Three docs updated:
- DEPLOY_METAL.md — Hetzner IP, Hetzner Console SSH fallback, Docker-
  install step, decommission note for the old Vultr box.
- DEPLOY_CHECKLIST.md — same IP swap throughout, plus an explicit DNS
  precondition (A-records must point at 178.104.208.252 before deploy)
  and a "decommission the Vultr box" line in first-day ops.
- DO_THIS_NOW.md — same swap, plus a Cloudflare-cache troubleshooting
  note for "site still shows old content after DNS flip".

No code changes. Pure documentation correction.
CC LABS App committed on May 13, 2026Parent: 1e79799
3 files changed+9266fe8ae12503ef61b2c017311d9cec427e5533348b
3 changed files+92−66
ModifiedDEPLOY_CHECKLIST.md+15−12View fileUnifiedSplit
11# Deploy checklist
22
3Scannable go-live runbook for the metal-box deploy at `45.76.171.37`.
4For the compose + Caddy setup, see `DEPLOY_METAL.md`. For the (deferred)
5Fly.io path, see `DEPLOY.md`.
3Scannable go-live runbook for the metal-box deploy at **Hetzner
4Gluecron-1, `178.104.208.252`**. For the bundled compose + Caddy setup,
5see `DEPLOY_METAL.md`. For the (deferred) Fly.io path, see `DEPLOY.md`.
66
77## Pre-deploy
88
9- [ ] DNS confirmed: `gluecron.com` + `www.gluecron.com` A-records point
10 at `178.104.208.252` (NOT the obsolete `45.76.171.37`), proxy
11 status "DNS only" in Cloudflare
912- [ ] `DATABASE_URL` set to a live Neon PostgreSQL connection string (hard-required)
1013- [ ] `.env` populated on the box from `.env.example`; optional keys
1114 (`ANTHROPIC_API_KEY`, `RESEND_API_KEY`, `GATETEST_API_KEY`, `VOYAGE_API_KEY`)
1720- [ ] Local: `bun run preflight` green
1821- [ ] Local: `bun test` clean on the deploy commit
1922- [ ] `CHANGELOG.md` has an `[Unreleased]` entry for this deploy
20- [ ] Cloudflare DNS confirmed: `gluecron.com` + `www.gluecron.com`
21 A-records point at `45.76.171.37`, proxy status "DNS only"
2223
23## Deploy (metal box, `45.76.171.37`)
24## Deploy (Hetzner Gluecron-1, `178.104.208.252`)
2425
2526```sh
26ssh root@45.76.171.37
27ssh root@178.104.208.252
28command -v docker >/dev/null || curl -fsSL https://get.docker.com | sh
2729git clone https://github.com/ccantynz-alt/Gluecron.com.git /opt/gluecron # first time
2830cd /opt/gluecron && git pull
29cp .env.example .env && vim .env # first time only
31cp .env.example .env && nano .env # first time only
3032docker compose up -d --build
3133docker compose logs -f caddy # watch for cert issuance
3234```
8284- [ ] Point Alertmanager at `infra/alerts/gluecron.rules.yml` (see `infra/alerts/README.md`)
8385- [ ] Dated entry added to `CHANGELOG.md`; tag a release
8486- [ ] Monitor `/metrics`, `/healthz`, and the error sink for the first hour
87- [ ] Decommission the obsolete Vultr box at `45.76.171.37` via the Vultr dashboard (only after DNS has fully propagated)
8588
8689## Redeploy
8790
8891```sh
89ssh root@45.76.171.37
92ssh root@178.104.208.252
9093cd /opt/gluecron && git pull && docker compose up -d --build
9194docker compose exec gluecron bun run db:migrate # if migrations changed
9295bash scripts/verify-deploy.sh https://gluecron.com
9598## Rollback
9699
97100```sh
98ssh root@45.76.171.37
101ssh root@178.104.208.252
99102cd /opt/gluecron
100103git log --oneline -10 # find last known-good sha
101104git checkout <prev-sha>
102105docker compose up -d --build
103106```
104107
105DNS is unchanged, so rollback = ~60s of rebuild time with no
106Cloudflare/registrar changes required.
108DNS is unchanged on rollback, so the failover is ~60s of rebuild time
109with no Cloudflare/registrar changes required.
ModifiedDEPLOY_METAL.md+36−25View fileUnifiedSplit
1# DEPLOY_METAL.md — metal-box deploy (interim)
1# DEPLOY_METAL.md — Hetzner Gluecron-1 deploy
22
3This is the shortest path to gluecron.com being live on the existing Vultr
4box at `45.76.171.37`. It's a stop-gap — everything migrates onto Crontech
5once Crontech is absorbing hosting, and DNS gets flipped (to Fly.io briefly
6or straight to Crontech) at that point. Don't polish this; throw it away
7later.
3Prod home: **Hetzner Cloud server `Gluecron-1`** at `178.104.208.252`
4(Falkenstein, eu-central, CPX22 x86 80GB). Replaces the obsolete Vultr
5box at `45.76.171.37`.
6
7This is the shortest path to gluecron.com being live on Hetzner. The
8`Dockerfile`, `docker-compose.yml`, and `Caddyfile` in the repo bring
9up the app + reverse proxy + auto-HTTPS in one command. Cloudflare DNS
10remains the resolver; Cloudflare proxying stays OFF so Let's Encrypt
11can complete HTTP-01.
812
913## What's already in place
1014
11- DNS: `gluecron.com` and `www.gluecron.com` A records point at
12 `45.76.171.37`. Proxy status is "DNS only" in Cloudflare — keep it that
13 way for the cert handshake.
14- `Dockerfile`, `docker-compose.yml`, and `Caddyfile` are all in the repo.
15 `docker compose up -d` brings up both the app and Caddy (auto-HTTPS via
16 Let's Encrypt).
17- App exposes `/healthz`, `/readyz`, `/status` per BUILD_BIBLE §2.6.
15- DNS target: `gluecron.com` + `www.gluecron.com` A-records should point at
16 `178.104.208.252`, proxy status "DNS only" (grey cloud) in Cloudflare.
17 If they still point at `45.76.171.37`, fix that first.
18- `Dockerfile`, `docker-compose.yml`, `Caddyfile` are all in the repo.
19 `docker compose up -d` brings up both the app and Caddy (auto-HTTPS
20 via Let's Encrypt).
21- App exposes `/healthz`, `/readyz`, `/status`, `/metrics`.
1822
1923## One-time box setup
2024
211. SSH in: `ssh root@45.76.171.37`
251. SSH in: `ssh root@178.104.208.252` (or use the Hetzner Console "Open Console" button)
22262. Install Docker (skip if already installed):
2327 ```sh
24 curl -fsSL https://get.docker.com | sh
28 command -v docker >/dev/null || curl -fsSL https://get.docker.com | sh
2529 ```
26303. Clone the repo:
2731 ```sh
2832 git clone https://github.com/ccantynz-alt/Gluecron.com.git /opt/gluecron
2933 cd /opt/gluecron
34 git checkout claude/new-session-xk1l7 # while this branch is the deploy target
3035 ```
314. Create `.env` (copy from `.env.example` and fill the real values — at
364. Create `.env` (copy from `.env.example` and fill real values — at
3237 minimum `DATABASE_URL` pointing at Neon):
3338 ```sh
3439 cp .env.example .env
35 vim .env
40 nano .env
3641 ```
3742
3843## Deploy
4348docker compose up -d --build
4449```
4550
46First run: Caddy requests a Let's Encrypt cert. Watch:
51First run: Caddy requests Let's Encrypt certs. Watch:
4752```sh
4853docker compose logs -f caddy
4954```
5257- `https://gluecron.com/healthz` → `ok`
5358- `https://gluecron.com/readyz` → `ok`
5459- `https://gluecron.com/status` → status page
60- `https://gluecron.com/metrics` → Prometheus-format metrics
5561
5662## First-time DB migration
5763
58After the container is up:
5964```sh
6065docker compose exec gluecron bun run db:migrate
6166```
7277cd /opt/gluecron && git checkout <prev-sha> && docker compose up -d --build
7378```
7479
75## When Crontech absorbs this
80## Decommission the old Vultr box
81
82The Vultr server at `45.76.171.37` was the previous home and now serves
83stale content. Once Hetzner Gluecron-1 is serving correctly and DNS has
84fully propagated (check from a phone on cellular), destroy the Vultr
85box via its provider dashboard.
86
87## When Crontech absorbs hosting
7688
771. Point DNS at the Crontech edge (Caddy on the Crontech box, or whatever
78 Crontech routes through).
792. Push gluecron.com via git to Crontech — BLK-009 deploy pipeline builds
80 and serves it.
813. Tear down this box. Nothing here is worth preserving.
89Gluecron stays where it is. Crontech-prod-01 (Hetzner, `178.156.251.6`,
90Ashburn) becomes the deploy target for additional empire projects via
91the BLK-009 git-push pipeline. Gluecron-1 keeps serving the git host +
92CI surface; Crontech keeps serving the deploy + runtime surface.
ModifiedDO_THIS_NOW.md+41−29View fileUnifiedSplit
22
33One page. Five steps. Copy-paste in order.
44
5## 1. SSH to the metal box
5Prod box: **Hetzner Gluecron-1 at `178.104.208.252`** (Falkenstein, eu-central).
6DNS target: `gluecron.com` + `www.gluecron.com` A-records → `178.104.208.252`,
7proxy status DNS only.
8
9## 1. SSH to the Hetzner box
610
711```sh
8ssh root@45.76.171.37
12ssh root@178.104.208.252
913```
1014
11If SSH key-only is enabled and your key isn't loaded, use Vultr's vSerial
12console from the dashboard — it accepts the root password from server
13Overview → "Show Password".
15If SSH key isn't loaded, use the Hetzner Console's **"Open Console"**
16button on the server detail page — it gives a browser-based root shell.
17
18## 2. Install Docker (first-time only)
19
20```sh
21command -v docker >/dev/null || curl -fsSL https://get.docker.com | sh
22```
1423
15## 2. Clone + configure (first-time only)
24## 3. Clone + configure (first-time only)
1625
1726```sh
1827git clone https://github.com/ccantynz-alt/Gluecron.com.git /opt/gluecron
1928cd /opt/gluecron
20git checkout claude/new-session-xk1l7 # the deploy + admin scripts live here
29git checkout claude/new-session-xk1l7
2130cp .env.example .env
22vim .env # set DATABASE_URL at minimum (Neon connection string)
31nano .env # set DATABASE_URL (Neon connection string) — required
2332```
2433
25Redeploy on later visits:
34Later redeploy:
2635
2736```sh
2837cd /opt/gluecron && git pull && docker compose up -d --build
2938```
3039
31## 3. Bring up the stack
40## 4. Bring up the stack
3241
3342```sh
3443docker compose up -d --build
3544docker compose logs -f caddy # ctrl-c once you see "certificate obtained"
36```
37
38Then run migrations:
39
40```sh
4145docker compose exec gluecron bun run db:migrate
4246```
4347
44## 4. Register your account
48If the cert handshake fails: confirm DNS resolves correctly
49(`dig +short gluecron.com` should print `178.104.208.252`), and that
50Cloudflare proxy is OFF (grey cloud) so Let's Encrypt can hit port 80
51directly.
4552
46- Open https://gluecron.com/register in a browser
47- Email + password. Use the same email you want to be admin under.
48- First registered user auto-promotes per bootstrap rule — but to be safe:
53## 5. Register your account
4954
50## 5. Confirm + promote yourself to admin
55- Open https://gluecron.com/register
56- Email + password. Use the email you want to be admin under.
57
58## 6. Confirm + promote yourself to admin
5159
5260```sh
5361docker compose exec gluecron bun run scripts/check-admin.ts you@example.com
5462```
5563
56If it says "NOT admin":
64If it says NOT admin:
5765
5866```sh
5967docker compose exec gluecron bun run scripts/promote-admin.ts you@example.com
6068```
6169
62Log out, log back in, visit https://gluecron.com/admin — should render.
70Log out, log back in, visit https://gluecron.com/admin.
6371
64## 6. Verify (optional but quick)
72## 7. Verify (optional but quick)
6573
6674```sh
6775bash scripts/verify-deploy.sh https://gluecron.com
6876```
6977
70All lines should show OK. If any FAIL, look at the line and debug just that.
78## 8. Decommission the obsolete box
79
80Once DNS resolves correctly to `178.104.208.252` and gluecron.com works
81from multiple networks (your phone on 4G is a good cache-bust), the old
82Vultr box at `45.76.171.37` can be destroyed via the Vultr dashboard.
83Don't rush this — give DNS 1–2 hours after the change.
7184
7285---
7386
7588
7689**Caddy logs say "acme: error issuing certificate":** DNS is wrong or
7790Cloudflare proxy is on. Check `dig +short gluecron.com` returns
78`45.76.171.37` and that the orange cloud is grey in Cloudflare.
91`178.104.208.252` and that the orange cloud is grey in Cloudflare.
7992
8093**`docker compose exec` says "service is not running":** check
8194`docker compose ps`. If gluecron is restarting, `docker compose logs gluecron`.
8497**`/register` returns 500:** DB migrations probably weren't run. Re-run
8598`docker compose exec gluecron bun run db:migrate`.
8699
87**"Cannot find module 'src/db/client'":** the scripts assume the working
88directory is the repo root inside the container, which is the default for
89`docker compose exec`. If you're running them on the host, prefix with
90`bun --cwd /opt/gluecron run scripts/...`.
100**Site still shows old content after DNS flip:** Cloudflare or local DNS
101cache. Check from a phone on cellular (`https://gluecron.com`) to
102bypass home/office caches.
91103