From cedb056bce8768b92ff3b1d14607d06baf238615 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Tue, 24 Mar 2026 08:00:43 -0500 Subject: [PATCH] =?UTF-8?q?docs:=20sync=20KB=20=E2=80=94=20database-deploy?= =?UTF-8?q?ment-guide.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- paper-dynasty/database-deployment-guide.md | 192 +++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 paper-dynasty/database-deployment-guide.md diff --git a/paper-dynasty/database-deployment-guide.md b/paper-dynasty/database-deployment-guide.md new file mode 100644 index 0000000..bfb407c --- /dev/null +++ b/paper-dynasty/database-deployment-guide.md @@ -0,0 +1,192 @@ +--- +title: "Paper Dynasty Database API — Deployment Guide" +description: "Complete deployment guide for the PD Database API covering dev and prod release flows, CI/CD pipeline, Docker tag strategy, rollback procedures, and common gotchas." +type: guide +domain: paper-dynasty +tags: [paper-dynasty, deployment, docker, gitea, ci-cd, database, release] +--- + +# Paper Dynasty Database API — Deployment Guide + +## Overview + +The Database API (`cal/paper-dynasty-database`) uses a tag-driven CI/CD pipeline via Gitea Actions. Pushing a git tag triggers a Docker image build and push to Docker Hub. There are two deployment tracks: + +| Track | Git Tag | Docker Tags | Environment | URL | +|---|---|---|---|---| +| **Production** | CalVer (e.g., `2026.3.6`) | `:2026.3.6` + `:production` | Prod | `pd.manticorum.com` | +| **Dev** | `dev` (force-updated) | `:dev` | Dev | `pddev.manticorum.com` | + +## Release Commands + +### Dev Deploy + +```bash +# Via release script (preferred) +bash /mnt/NV2/Development/paper-dynasty/.claude/skills/release/release.sh database dev + +# Manual +cd /mnt/NV2/Development/paper-dynasty/database +git checkout main && git pull --ff-only origin main +git tag -f dev && git push origin dev --force +``` + +The `dev` tag is **force-updated** every time — it always points to the latest commit you want to test. This is safe because the dev environment is not customer-facing. + +### Production Deploy + +```bash +# Auto-increment version (preferred) +bash /mnt/NV2/Development/paper-dynasty/.claude/skills/release/release.sh database + +# Explicit version +bash /mnt/NV2/Development/paper-dynasty/.claude/skills/release/release.sh database 2026.3.7 +``` + +CalVer format: `YYYY.M.BUILD` (e.g., `2026.3.6`). The script auto-increments BUILD if omitted. + +## CI/CD Pipeline + +**Workflow file:** `.gitea/workflows/build.yml` + +**Trigger:** Push of tags matching `20*` (CalVer) or `dev` + +**Steps:** +1. Checkout code with full history +2. Set up Docker Buildx with layer caching +3. Login to Docker Hub (`manticorum67`) +4. Build and push image with appropriate tags +5. Rotate build cache +6. Send Discord notification (success/failure) + +**Docker image:** `manticorum67/paper-dynasty-database` + +**Build cache:** Persistent volume `pd-buildx-cache` on the Gitea runner — significantly speeds up rebuilds since only changed layers are rebuilt. + +## Post-Build: Pulling the New Image + +CI builds and pushes the image, but **does not auto-deploy**. You must pull and restart the container on the target host. + +### Dev Environment + +```bash +ssh pd-database "cd /home/cal/container-data/dev-pd-database && docker compose pull && docker compose up -d" +``` + +- Host: `pd-database` (SSH alias) +- Container data: `/home/cal/container-data/dev-pd-database/` +- Container: `dev_pd_database` +- Port: 813 (mapped to internal 8000) +- URL: `pddev.manticorum.com` + +### Production Environment + +```bash +ssh akamai "cd /root/container-data/paper-dynasty && docker compose pull && docker compose up -d" +``` + +- Host: `akamai` (SSH alias) +- Container: `pd_api` +- Port: 815 (mapped to internal 8000) +- URL: `pd.manticorum.com` + +## Verification + +### Quick Curl Test + +```bash +# Dev +curl -s https://pddev.manticorum.com/api/v2/awards?limit=2 | python3 -m json.tool + +# Prod +curl -s https://pd.manticorum.com/api/v2/awards?limit=2 | python3 -m json.tool +``` + +### Smoke Test + +Use the `/smoke-test` skill: +``` +/smoke-test dev +/smoke-test prod +``` + +### Check Running Version + +```bash +# Dev — check container image digest +ssh pd-database "docker inspect dev_pd_database --format '{{.Image}}'" + +# Prod +ssh akamai "docker inspect pd_api --format '{{.Image}}'" +``` + +## Rollback + +### Dev + +Just re-tag `dev` to a known-good commit and force-push: + +```bash +git tag -f dev +git push origin dev --force +# Then pull on dev host +ssh pd-database "cd /home/cal/container-data/paper-dynasty-database && docker compose pull && docker compose up -d" +``` + +### Production + +Production images are tagged with both the CalVer version and `:production`. To roll back: + +```bash +# On the prod host, pull a specific older version +ssh akamai "docker pull manticorum67/paper-dynasty-database:2026.3.5" +# Update compose to pin to that version, or just retag +ssh akamai "cd /root/container-data/paper-dynasty && docker compose up -d" +``` + +## Common Gotchas + +### CalVer tag does NOT deploy to dev + +CalVer tags (e.g., `2026.3.6`) only build `:version` + `:production` Docker tags. The dev environment pulls `:dev`. You **must** push the `dev` git tag separately to deploy to dev. + +### CI build takes ~2-3 minutes + +After pushing a tag, wait for CI to complete before pulling on the host. Check the Gitea Actions tab or wait for the Discord notification. + +### "dev" tag requires force-push + +Since `dev` is reused, you must use `git tag -f dev` and `git push origin dev --force`. The release script handles this automatically. + +### Branch protection doesn't affect tags + +Tags can be pushed by anyone with write access — no PR or review required. The review happens before merging to `main`; tagging is the release step. + +### scout_opportunities.py was base64-encoded + +As of 2026-03-24, this file was stored as raw base64 in git. The `total-count-pagination` branch rewrote it to proper Python source. If you see base64 content in this file on older branches, that's expected — it's a legacy artifact. + +### Multiple PRs merging concurrently causes rebase races + +When merging many PRs at once (e.g., batch pagination PRs), branch protection rules (`block_on_outdated_branch` + `dismiss_stale_approvals`) cause a merge storm. Each rebase invalidates the approval, requiring re-approve + re-merge. pd-ops agents handle this automatically but may take several attempts. + +## Environment Variables + +| Var | Purpose | +|---|---| +| `API_TOKEN` | Bearer token for authenticated endpoints | +| `LOG_LEVEL` | Logging verbosity (default: INFO) | +| `DATABASE_TYPE` | `postgresql` | +| `POSTGRES_HOST` | Container name of PostgreSQL | +| `POSTGRES_DB` | Database name (`pd_master`) | +| `POSTGRES_USER` | DB username | +| `POSTGRES_PASSWORD` | DB password | + +## Topology Quick Reference + +| Component | Host | Container | Port | +|---|---|---|---| +| Database API (prod) | `ssh akamai` | `pd_api` | 815 | +| Database API (dev) | `ssh pd-database` | `dev_pd_database` | 813 | +| PostgreSQL (prod) | `ssh akamai` | `pd_postgres` | 5432 | +| PostgreSQL (dev) | `ssh pd-database` | `pd_postgres` | 5432 |