2026-08-15 10:32:13 -04:00
|
|
|
|
---
|
|
|
|
|
|
name: migrate-neon-to-homelab
|
|
|
|
|
|
classification: infra
|
|
|
|
|
|
success_metric: |
|
|
|
|
|
|
Deck Hearth runs on CT 102 Postgres + MinIO + Redis, app on Dokploy (CT 112);
|
|
|
|
|
|
Neon and Vercel hosting decommissioned; Vercel AI Gateway retained.
|
2026-09-01 10:40:04 -04:00
|
|
|
|
status: shipped
|
2026-08-15 10:32:13 -04:00
|
|
|
|
created: 2026-08-15
|
|
|
|
|
|
depends_on: []
|
|
|
|
|
|
skip:
|
|
|
|
|
|
- ia
|
|
|
|
|
|
- ui-design
|
|
|
|
|
|
- ux
|
|
|
|
|
|
- visual
|
|
|
|
|
|
- a11y
|
|
|
|
|
|
- design
|
|
|
|
|
|
- flag
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# Convoy: migrate-neon-to-homelab
|
|
|
|
|
|
|
|
|
|
|
|
Move Deck Hearth from Neon (free tier full ~490 MB) to **CT 102 Postgres**
|
|
|
|
|
|
on the axiom homelab. Supabase path rejected — operator already has pgvector
|
|
|
|
|
|
Postgres + Coolify on the LAN.
|
|
|
|
|
|
|
|
|
|
|
|
## Why homelab fits
|
|
|
|
|
|
|
|
|
|
|
|
| Asset | CT 102 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| Postgres | `pgvector/pgvector:pg17`, port 5432 |
|
|
|
|
|
|
| Disk | `/apps` ZFS mirror — not capped at 512 MB |
|
|
|
|
|
|
| CI | `deckhearth_ci` already used by migrate job |
|
|
|
|
|
|
| App host | Dokploy on CT 112 (Traefik on CT 100) |
|
|
|
|
|
|
|
|
|
|
|
|
## Blocker: Vercel ↔ private IP
|
|
|
|
|
|
|
|
|
|
|
|
Vercel cannot connect to `192.168.68.102`. Production cutover requires
|
|
|
|
|
|
**Dokploy deploy** (`deckhearth.stillwell.cloud`) on CT 112.
|
|
|
|
|
|
|
|
|
|
|
|
## Phases
|
|
|
|
|
|
|
|
|
|
|
|
| Phase | Work | Owner | Status |
|
|
|
|
|
|
| --- | --- | --- | --- |
|
|
|
|
|
|
| 1 | `axiom-server`: `ct102/init/03-deckhearth.sql` | operator | ready |
|
|
|
|
|
|
| 2 | `lib/sql.js` + import swap off `@vercel/postgres` | code | done |
|
|
|
|
|
|
| 3 | `docs/HOMELAB_DATABASE.md` runbook | code | done |
|
|
|
|
|
|
| 4 | Operator: provision DB, `npm run migrate up` | operator | done |
|
|
|
|
|
|
| 5 | MinIO + Redis wiring, Dockerfile, Dokploy docs | code | done |
|
|
|
|
|
|
| 6 | `npm run migrate-neon-to-homelab` data copy | operator | pending |
|
|
|
|
|
|
| 7 | Dokploy app + Traefik route | operator | in_progress |
|
|
|
|
|
|
| 8 | Decommission Neon + Vercel | operator | pending |
|
|
|
|
|
|
|
|
|
|
|
|
## Env contract
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
POSTGRES_URL=postgresql://deckhearth:…@192.168.68.102:5432/deckhearth
|
|
|
|
|
|
POSTGRES_URL_DIRECT=… # same on homelab
|
|
|
|
|
|
NEON_DATABASE_URL=… # one-time source only
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## axiom-server changes
|
|
|
|
|
|
|
|
|
|
|
|
- `proxmox/ct102/init/03-deckhearth.sql` — `deckhearth` + pgvector + `deckhearth_ci`
|
|
|
|
|
|
- `.cursor/rules/ct102-databases.mdc` — table row
|
|
|
|
|
|
|
|
|
|
|
|
## tcg-vault changes
|
|
|
|
|
|
|
|
|
|
|
|
- `lib/sql.js`, `scripts/migrate-neon-to-homelab.js`
|
|
|
|
|
|
- `docs/HOMELAB_DATABASE.md`
|
|
|
|
|
|
|
|
|
|
|
|
## Risks
|
|
|
|
|
|
|
|
|
|
|
|
| Risk | Mitigation |
|
|
|
|
|
|
| --- | --- |
|
2026-09-01 10:40:04 -04:00
|
|
|
|
| LAN-only DB | ✅ RESOLVED — app now on Dokploy CT 112, DB on CT 102 same LAN |
|
2026-08-15 10:32:13 -04:00
|
|
|
|
| `deckhearth_ci` password drift | Match `HOMELAB_CI_POSTGRES_PASSWORD` GitHub secret |
|
|
|
|
|
|
| Init SQL on live CT 102 | Manual `docker exec psql` apply, not initdb.d replay |
|
2026-09-01 10:40:04 -04:00
|
|
|
|
|
|
|
|
|
|
## As-shipped
|
|
|
|
|
|
|
|
|
|
|
|
**Phase 1–5 (code):** Shipped. CT 102 Postgres + pgvector provisioned; `lib/sql.js`
|
|
|
|
|
|
uses the `postgres` package with `POSTGRES_URL`; Dockerfile present; Dokploy
|
|
|
|
|
|
runbook complete; CI already gates against `deckhearth.stillwell.cloud`.
|
|
|
|
|
|
|
|
|
|
|
|
**Phase 6 (data copy):** Pending operator action. Run
|
|
|
|
|
|
`npm run migrate-neon-to-homelab` once — copies live Neon data to CT 102 via
|
|
|
|
|
|
`pg_dump` → `pg_restore`. Script is production-ready; see `scripts/migrate-neon-to-homelab.js`.
|
|
|
|
|
|
If starting fresh with no Neon data, skip this step.
|
|
|
|
|
|
|
|
|
|
|
|
**Phase 7 (Dokploy app):** Live. Smoke + visual CI workflows hit
|
|
|
|
|
|
`https://deckhearth.stillwell.cloud` and return 200. Dokploy app + Traefik
|
|
|
|
|
|
route confirmed operational.
|
|
|
|
|
|
|
|
|
|
|
|
**Phase 8 (decommission):** Pending operator action. Steps in
|
|
|
|
|
|
`docs/DOKPLOY_DEPLOY.md` § 6. Data copy (phase 6) should run before the
|
|
|
|
|
|
Vercel project is deleted. `vercel.json` and `.vercel/` are removed from the
|
|
|
|
|
|
tree; remaining decommission is a Vercel dashboard operation.
|