From fa7e4cf4c710356a9e5f0511defe7ff28ab51785 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Fri, 13 Mar 2026 08:34:11 -0500 Subject: [PATCH] Add Paper Dynasty dev server guide Comprehensive reference for dev and prod API servers including: - Server architecture and quick reference table - SSH access, container management, deploy procedures - File system layout, card cache management - Database access for both environments - Docker image tags and CI pipeline - Networking and DNS configuration - Troubleshooting common issues Co-Authored-By: Claude Opus 4.6 --- paper-dynasty/dev-server-guide.md | 319 ++++++++++++++++++++++++++++++ 1 file changed, 319 insertions(+) create mode 100644 paper-dynasty/dev-server-guide.md diff --git a/paper-dynasty/dev-server-guide.md b/paper-dynasty/dev-server-guide.md new file mode 100644 index 0000000..184e98a --- /dev/null +++ b/paper-dynasty/dev-server-guide.md @@ -0,0 +1,319 @@ +--- +title: Paper Dynasty Dev Server Guide +domain: development +type: guide +tags: + - paper-dynasty + - docker + - deployment + - postgresql + - ssh +--- + +# Paper Dynasty Dev Server Guide + +Comprehensive reference for accessing, deploying, and troubleshooting the Paper Dynasty dev (and prod) API servers. + +## Server Architecture + +``` + ┌─────────────────────────────────────────────┐ + │ akamai (172.237.147.99) │ + pd.manticorum.com │ pd_api (:8002) → manticorum67/paper- │ + (Cloudflare CDN) │ dynasty-database:latest │ + │ Postgres: pd_master (sba_postgres) │ + │ Nginx Proxy Manager → reverse proxy │ + └─────────────────────────────────────────────┘ + + ┌─────────────────────────────────────────────┐ + │ pd-database / sba-db (10.10.0.42) │ + pddev.manticorum │ dev_pd_database (:813) → manticorum67/ │ + .com (local) │ paper-dynasty-database:dev │ + │ Postgres: paperdynasty_dev (sba_postgres) │ + │ Also runs: sba_db_api, sba_adminer, │ + │ sba_postgres, sba_redis │ + └─────────────────────────────────────────────┘ +``` + +## Quick Reference + +| Environment | URL | Server | SSH Alias | Container | Image Tag | Port | DB Name | +|-------------|-----|--------|-----------|-----------|-----------|------|---------| +| **Production** | `pd.manticorum.com/api` | akamai (172.237.147.99) | `akamai` | `pd_api` | `:latest` | 8002 | `pd_master` | +| **Dev** | `pddev.manticorum.com/api` | pd-database (10.10.0.42) | `pd-database` | `dev_pd_database` | `:dev` | 813 | `paperdynasty_dev` | + +**API Token** (both envs): `Tp3aO3jhYve5NJF1IqOmJTmk` + +## SSH Access + +```bash +# Dev server (all these aliases work) +ssh pd-database # or: sba-db, strat-database, pd-db, strat-db, sba-database +# → 10.10.0.42, user: cal + +# Prod server +ssh akamai # or: akamai-nano +# → 172.237.147.99, user: root +``` + +## Dev Server Operations + +### Container Management + +```bash +# Check status +ssh pd-database "docker ps --filter name=dev_pd_database --format '{{.Names}}\t{{.Image}}\t{{.Status}}'" + +# View logs (stdout/stderr) +ssh pd-database "docker logs dev_pd_database --tail 100" +ssh pd-database "docker logs dev_pd_database -f --tail 50" # follow + +# View application logs (file-based, by date) +ssh pd-database "cat /home/cal/container-data/dev-pd-database/logs/database/$(date +%Y-%-m-%-d).log" +``` + +### Deploy New Dev Image + +The CI pipeline pushes `manticorum67/paper-dynasty-database:dev` on PR builds to main. + +```bash +# Standard deploy (compose file already uses :dev tag) +ssh pd-database "cd /home/cal/container-data/dev-pd-database && docker compose pull && docker compose up -d" +``` + +**If the container name conflicts** (orphaned from previous non-compose run): +```bash +ssh pd-database "docker stop dev_pd_database && docker rm dev_pd_database && cd /home/cal/container-data/dev-pd-database && docker compose up -d" +``` + +### Health Check + +```bash +# Quick status code check +curl -sL -o /dev/null -w "%{http_code}" "https://pddev.manticorum.com/api/v2/players/?limit=1" \ + -H "Authorization: Bearer Tp3aO3jhYve5NJF1IqOmJTmk" + +# Time a card render (fresh, no cache) +curl -sL -o /dev/null -w "HTTP %{http_code} | Total: %{time_total}s | TTFB: %{time_starttransfer}s\n" \ + "https://pddev.manticorum.com/api/v2/players/12726/battingcard?d=$(date +%Y-%m-%d-%s)" + +# Test HTML card render +# Append &html=true for HTML output (useful for debugging card layout) +curl -sL "https://pddev.manticorum.com/api/v2/players/12726/battingcard?d=$(date +%Y-%m-%d)&html=true" +``` + +### File System Layout + +``` +/home/cal/container-data/dev-pd-database/ +├── docker-compose.yml # Compose config +├── storage/ # Mounted → /usr/src/app/storage +│ ├── templates/ # HTML card templates (style.html, player_card.html) +│ ├── cards/ # Cached rendered card PNGs +│ │ └── cardset-{id}/ +│ │ ├── batting/ # {player_id}-{date}-v{variant}.png +│ │ └── pitching/ +│ ├── static/ # Static assets +│ ├── card_creation.db # Legacy SQLite (unused in PostgreSQL mode) +│ └── *.csv # Scouting report data +└── logs/ + └── database/ + └── {YYYY}-{M}-{D}.log # Application logs (date format: no zero-padding) +``` + +### Clear Card Cache (Force Re-render) + +```bash +# Clear specific player +ssh pd-database "rm -f /home/cal/container-data/dev-pd-database/storage/cards/cardset-27/batting/12726-*.png" + +# Clear all cached cards for a cardset +ssh pd-database "rm -rf /home/cal/container-data/dev-pd-database/storage/cards/cardset-27/" + +# Alternative: use cache-busting query param (changes the ?d= value) +curl -sL "https://pddev.manticorum.com/api/v2/players/12726/battingcard?d=2026-3-13-$(date +%s)" +``` + +### Database Access + +Dev uses `paperdynasty_dev` on the shared `sba_postgres` container (same server, port 5432). + +```bash +# Direct psql +ssh pd-database "docker exec -it sba_postgres psql -U sba_admin -d paperdynasty_dev" + +# Adminer web UI +# http://10.10.0.42:8080 +# Server: sba_postgres | User: sba_admin | Password: your_production_password | DB: paperdynasty_dev + +# Quick query +ssh pd-database "docker exec sba_postgres psql -U sba_admin -d paperdynasty_dev -c 'SELECT count(*) FROM player WHERE cardset_id = 27'" +``` + +## Production Server Operations + +### Container Management + +```bash +# Check status +ssh akamai "docker ps --filter name=pd_api --format '{{.Names}}\t{{.Image}}\t{{.Status}}'" + +# View logs +ssh akamai "docker logs pd_api --tail 100" +``` + +### Deploy to Production + +Production uses `:latest` tag. After merging to main, CI pushes both `:latest` and a CalVer tag. + +```bash +ssh akamai "cd /root/container-data/paper-dynasty && docker compose pull && docker compose up -d" +``` + +### File System Layout (Prod) + +``` +/root/container-data/paper-dynasty/ +├── docker-compose.yml +├── storage/ # Card cache, templates, scouting data +│ └── cards/cardset-{id}/... +└── logs/ + └── database/ +``` + +### Database Access (Prod) + +Production uses `pd_master` database with `pd_admin` user on the shared `sba_postgres` on akamai. + +```bash +ssh akamai "docker exec -it sba_postgres psql -U pd_admin -d pd_master" +``` + +## Docker Image Tags + +| Tag | Source | When Pushed | Use | +|-----|--------|-------------|-----| +| `:latest` | `main` branch merge | On merge to main | Production | +| `:dev` | PR to `main` | On PR creation/update | Dev testing | +| `:YYYY.MM.BUILD` | `main` branch merge | On merge to main | Versioned releases | +| `:rc-SHA` | `next-release` push | On push to next-release | Release candidates | + +CI pipeline: `.gitea/workflows/build.yml` in `paper-dynasty-database` repo. + +## Docker Compose Config (Dev) + +```yaml +services: + database: + image: manticorum67/paper-dynasty-database:dev + restart: unless-stopped + container_name: dev_pd_database + volumes: + - ./storage:/usr/src/app/storage + - ./logs:/usr/src/app/logs + ports: + - 813:80 + environment: + - TESTING=True + - LOG_LEVEL=INFO + - API_TOKEN=Tp3aO3jhYve5NJF1IqOmJTmk + - TZ=America/Chicago + - WORKERS_PER_CORE=1.0 + - PRIVATE_IN_SCHEMA=TRUE + - DATABASE_TYPE=postgresql + - POSTGRES_DB=paperdynasty_dev + - POSTGRES_USER=sba_admin + - POSTGRES_PASSWORD=your_production_password + - POSTGRES_HOST=sba_postgres + - POSTGRES_PORT=5432 +networks: + default: + external: + name: dev-sba-database_default +``` + +**Key differences from prod:** +- `TESTING=True` (enables private endpoints in schema) +- `PRIVATE_IN_SCHEMA=TRUE` (shows all endpoints in Swagger) +- `WORKERS_PER_CORE=1.0` (fewer workers than prod's 1.5) +- No healthcheck configured (prod has one) +- No `WORKER_TIMEOUT` set (prod uses 180s) + +## Networking + +- **Dev**: Joins `dev-sba-database_default` network to reach `sba_postgres` on the same host +- **Prod**: Joins both `sba-database_default` (for postgres) and `nginx-proxy-manager_npm_network` (for reverse proxy) on akamai +- **DNS**: `pd.manticorum.com` → Cloudflare → akamai:8002; `pddev.manticorum.com` → local DNS → 10.10.0.42:813 + +## Troubleshooting + +### Container won't start (name conflict) + +``` +Error: container name "/dev_pd_database" is already in use +``` + +The old container was started outside compose tracking. Remove it manually: +```bash +ssh pd-database "docker stop dev_pd_database; docker rm dev_pd_database" +ssh pd-database "cd /home/cal/container-data/dev-pd-database && docker compose up -d" +``` + +### Card renders return 502 + +Usually means Chromium crashed inside the container. Check logs and restart: +```bash +ssh pd-database "docker logs dev_pd_database --tail 20" +ssh pd-database "cd /home/cal/container-data/dev-pd-database && docker compose restart" +``` + +With the persistent browser (Phase 0), `get_browser()` auto-reconnects on the next request. If it persists, the container may need more memory (Chromium needs ~100MB per page). + +### Application logs missing for today + +Log files use non-zero-padded date format: `2026-3-13.log` not `2026-03-13.log`. + +```bash +# Correct +ssh pd-database "cat /home/cal/container-data/dev-pd-database/logs/database/$(date +%Y-%-m-%-d).log" +``` + +### Database connection errors + +Verify the postgres container is running and the network is correct: +```bash +ssh pd-database "docker ps --filter name=sba_postgres" +ssh pd-database "docker exec dev_pd_database ping -c1 sba_postgres" +``` + +### Stale card images (old render showing) + +Cards are cached as PNG files on disk. Either delete the file or use a new `?d=` cache-buster value: +```bash +# Option 1: Delete cached file +ssh pd-database "rm /home/cal/container-data/dev-pd-database/storage/cards/cardset-27/batting/12726-*.png" + +# Option 2: Use different date param (generates new file, old one remains) +curl "https://pddev.manticorum.com/api/v2/players/12726/battingcard?d=2026-3-13-$(date +%s)" +``` + +## Server Hardware + +| Spec | pd-database (dev) | akamai (prod) | +|------|-------------------|---------------| +| Hostname | databases-bots | akamai | +| IP | 10.10.0.42 (homelab) | 172.237.147.99 (Linode) | +| OS | Ubuntu 22.04 (6.8 kernel) | — | +| RAM | 16 GB | — | +| Disk | 503 GB (24% used) | — | +| Docker | 24.0.6 / Compose 2.21 | — | + +## Related Compose Stacks on pd-database + +| Stack | Path | Purpose | +|-------|------|---------| +| `dev-pd-database` | `/home/cal/container-data/dev-pd-database/` | PD dev API | +| `pd-database` | `/home/cal/container-data/pd-database/` | PD legacy (stopped) | +| `dev-sba-database` | `/home/cal/container-data/dev-sba-database/` | Major Domo dev API | +| `sba-database` | `/home/cal/container-data/sba-database/` | Major Domo prod API | +| `postgres-database` | `/home/cal/container-data/postgres-database/` | Shared PostgreSQL + Adminer |