deckhearth/docs/DOKPLOY_DEPLOY.md
Randall Stillwell a81c6dc21b fix(tests): wire DEFAULT_LAYOUT export, fix custom-frames mocks, and add validateLayout tests
- Export DEFAULT_LAYOUT from lib/frame-palette.js so the custom-frames
  route can import it at runtime (not just the hardcoded copy in tests).
- Fix vitest mock isolation in test/api/custom-frames.test.js: beforeEach now
  uses mockReturnValue instead of mockResolvedValue to avoid resolving the
  default mock in each test; test cases provide specific mock chains with
  mockResolvedValueOnce. Fixes 4 tests that were bleeding state between
  cases due to leftover queued mock values.
- Fix validateLayout test coordinates: art w+h=0.924 and 0.398 are both
  within the 0-1 fraction range so x+w=0.962<1 and y+h=0.982<1 pass.
- Add dedicated validateLayout unit tests (accepts, rejects missing zone,
  rejects out-of-bounds).
- Fix update test mock chain: PUT calls SELECT (found) then SELECT (clash)
  then UPDATE (RETURNING) — provide all three in order.
- Fix DELETE test: owns via SELECT then executes DELETE (2 calls).
2026-09-01 09:40:04 -05:00

3.1 KiB

Deck Hearth on Dokploy (CT 112)

Homelab deploy: Postgres + Redis + MinIO on CT 102, app on Dokploy, public URL via CT 100 Traefik → CT 112.

1. Prerequisites (CT 102)

  • deckhearth Postgres — provision-deckhearth.sh
  • MinIO bucket — provision-deckhearth-minio.sh (axiom-server)
  • Neon data copy — npm run migrate-neon-to-homelab (one-time; run once then archive Neon. Script reads NEON_DATABASE_URL (source) and POSTGRES_URL_DIRECT (target). Requires pg_dump + pg_restore on PATH. If starting fresh with no Neon data, skip this step.)

2. Dokploy application

Dashboard: https://dokploy.stillwell.cloud

Setting Value
Source Git (Forgejo/GitHub) → this repo
Build type Dockerfile
Dockerfile path Dockerfile (repo root — must be pushed to GitHub)
Branch main (production)
Domain in Dokploy http://deckhearth.stillwell.cloud (use http://, not https://)
Port 3000

3. Environment variables (Dokploy → Environment)

# Database (CT 102)
POSTGRES_URL=postgresql://deckhearth:YOUR_PASSWORD@192.168.68.102:5432/deckhearth

# Redis rate limits (CT 102, DB index 5)
REDIS_URL=redis://:YOUR_REDIS_PASSWORD@192.168.68.102:6379/5

# MinIO object storage (CT 102)
S3_ENDPOINT=http://192.168.68.102:9000
S3_ACCESS_KEY_ID=deckhearth-app
S3_SECRET_ACCESS_KEY=YOUR_MINIO_SECRET
S3_BUCKET=deckhearth
S3_PUBLIC_BASE_URL=https://cdn.stillwell.cloud/deckhearth
S3_REGION=us-east-1

# Auth
JWT_SECRET=openssl rand -base64 32

# AI (kept on Vercel AI Gateway)
AI_GATEWAY_API_KEY=vck_…

# Email (external — Resend until self-hosted)
RESEND_API_KEY=re_…

# Cron (n8n on CT 105 hits this weekly)
CRON_SECRET=openssl rand -base64 24

# Optional
NODE_ENV=production

4. Traefik (CT 100)

Route added in axiom-server/proxmox/ct100/traefik/config/dynamic/ct112-dokploy.yml:

  • Host: deckhearth.stillwell.cloud
  • Backend: http://192.168.68.112:80 (Dokploy Traefik)

After editing locally: ./proxmox/scripts/sync.sh push-traefik

5. Catalog sync cron (replaces Vercel Cron)

Vercel vercel.json crons are removed. Schedule in n8n (CT 105) or cron:

curl -fsS -H "Authorization: Bearer $CRON_SECRET" \
  https://deckhearth.stillwell.cloud/api/cron/sync-catalog

Weekly: 0 6 * * 1 (Mondays 06:00).

6. Decommission Vercel

  1. Run the data copy firstnpm run migrate-neon-to-homelab (see § 1). If there is no Neon data to migrate, skip to step 2.
  2. Verify DNS — confirm deckhearth.stillwell.cloud resolves to Traefik (CT 100). Already configured for *.stillwell.cloud → CT 100; verify in your DNS provider or AdGuard.
  3. Delete the Vercel project at vercel.com. After confirming the Dokploy deployment is stable and serving traffic, delete the Vercel project to stop billing and auto-deploys.
  4. Remove old env vars from Vercel dashboard — Neon connection string, Blob storage, Upstash/Redis vars are no longer used by the app.

7. Local dev

Same env vars in .env.local with homelab URLs (LAN required).

npm run dev