From 39a7d59fcd31ec933fa969f69cf266448e094104 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Fri, 7 Nov 2025 13:07:23 -0600 Subject: [PATCH] CLAUDE: Add docker-compose.yml and quickstart guide - PostgreSQL 17 Alpine container with health checks - Adminer database UI on port 8080 - Persistent volumes for data - Environment variable support via .env - Comprehensive quickstart guide with common commands - Troubleshooting section - Production considerations - Update .gitignore to allow base docker-compose.yml --- .gitignore | 3 +- DOCKER_QUICKSTART.md | 352 +++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 64 ++++++++ 3 files changed, 418 insertions(+), 1 deletion(-) create mode 100644 DOCKER_QUICKSTART.md create mode 100644 docker-compose.yml diff --git a/.gitignore b/.gitignore index 0b9e9bf..2bc8d5f 100644 --- a/.gitignore +++ b/.gitignore @@ -56,7 +56,8 @@ Scripts/ storage/ pyenv.cfg pyvenv.cfg -docker-compose* +docker-compose.override.yml +docker-compose.*.yml *.db venv .claude/ diff --git a/DOCKER_QUICKSTART.md b/DOCKER_QUICKSTART.md new file mode 100644 index 0000000..f70b4e1 --- /dev/null +++ b/DOCKER_QUICKSTART.md @@ -0,0 +1,352 @@ +# Docker Quick Start Guide + +## ๐Ÿš€ Starting PostgreSQL for Local Development + +### Option 1: Using Docker Compose (Recommended) + +**Start PostgreSQL + Adminer (database UI):** +```bash +# Start the database +docker-compose up -d postgres adminer + +# Or use podman-compose +podman-compose up -d postgres adminer +``` + +**What this does:** +- โœ… Starts PostgreSQL 17 on port 5432 +- โœ… Starts Adminer (database UI) on port 8080 +- โœ… Creates persistent volume for database data +- โœ… Sets up health checks + +**Access Adminer:** +- Open browser: http://localhost:8080 +- System: `PostgreSQL` +- Server: `pd_postgres` (or `localhost` if connecting from host) +- Username: `pd_admin` (from .env or default) +- Password: `pd_dev_password` (from .env or default) +- Database: `pd_master` (from .env or default) + +--- + +### Option 2: Native Docker/Podman Commands + +**Start PostgreSQL container:** +```bash +# Using docker +docker run -d \ + --name pd_postgres \ + -e POSTGRES_DB=pd_master \ + -e POSTGRES_USER=pd_admin \ + -e POSTGRES_PASSWORD=pd_dev_password \ + -p 5432:5432 \ + -v pd_postgres_data:/var/lib/postgresql/data \ + postgres:17-alpine + +# Using podman +podman run -d \ + --name pd_postgres \ + -e POSTGRES_DB=pd_master \ + -e POSTGRES_USER=pd_admin \ + -e POSTGRES_PASSWORD=pd_dev_password \ + -p 5432:5432 \ + -v pd_postgres_data:/var/lib/postgresql/data \ + postgres:17-alpine +``` + +--- + +## ๐Ÿ“ Common Commands + +### Start Services +```bash +# Start all services +docker-compose up -d + +# Start specific services +docker-compose up -d postgres adminer + +# Start and view logs +docker-compose up postgres adminer +``` + +### Stop Services +```bash +# Stop all services +docker-compose down + +# Stop and remove volumes (โš ๏ธ deletes database data) +docker-compose down -v +``` + +### View Logs +```bash +# View all logs +docker-compose logs -f + +# View PostgreSQL logs only +docker-compose logs -f postgres + +# View last 50 lines +docker-compose logs --tail=50 postgres +``` + +### Check Status +```bash +# List running containers +docker-compose ps + +# Or with native docker/podman +docker ps -a +podman ps -a +``` + +### Database Backup +```bash +# Backup database +docker exec pd_postgres pg_dump -U pd_admin pd_master > backup_$(date +%Y%m%d).sql + +# Or with podman +podman exec pd_postgres pg_dump -U pd_admin pd_master > backup_$(date +%Y%m%d).sql +``` + +### Database Restore +```bash +# Restore from backup +docker exec -i pd_postgres psql -U pd_admin pd_master < backup_20251107.sql + +# Or with podman +podman exec -i pd_postgres psql -U pd_admin pd_master < backup_20251107.sql +``` + +--- + +## ๐Ÿ”ง Configuration + +### Environment Variables + +Create a `.env` file (or use `.env.example` as a template): + +```bash +# Database Configuration +POSTGRES_DB=pd_master +POSTGRES_USER=pd_admin +POSTGRES_PASSWORD=pd_dev_password +POSTGRES_PORT=5432 + +# Application Configuration +LOG_LEVEL=INFO +API_TOKEN=dev_token_here +TZ=America/New_York +``` + +Docker Compose will automatically load these variables. + +--- + +## ๐Ÿงช Testing Database Connection + +### From Host Machine + +**Using psql (if installed):** +```bash +psql -h localhost -U pd_admin -d pd_master +# Enter password when prompted +``` + +**Using Python:** +```bash +# Set environment variables first +export DATABASE_TYPE=postgresql +export POSTGRES_HOST=localhost +export POSTGRES_DB=pd_master +export POSTGRES_USER=pd_admin +export POSTGRES_PASSWORD=pd_dev_password + +# Test connection +python -c "from app.db_engine import db; db.connect(); print('โœ“ Connected'); db.close()" +``` + +### From Inside Container + +```bash +# Connect to PostgreSQL container +docker exec -it pd_postgres psql -U pd_admin -d pd_master + +# Or with podman +podman exec -it pd_postgres psql -U pd_admin -d pd_master + +# Common psql commands: +# \dt - List tables +# \d table - Describe table +# \l - List databases +# \du - List users +# \q - Quit +``` + +--- + +## ๐Ÿƒ Running the Application + +### Option 1: Local Python (Recommended for Development) + +```bash +# Ensure PostgreSQL is running in Docker +docker-compose up -d postgres + +# Set environment variables +export DATABASE_TYPE=postgresql +export POSTGRES_HOST=localhost +export POSTGRES_DB=pd_master +export POSTGRES_USER=pd_admin +export POSTGRES_PASSWORD=pd_dev_password + +# Install dependencies +pip install -r requirements.txt + +# Run with hot reload +uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 +``` + +**Benefits:** +- โœ… Fast hot-reload during development +- โœ… Easy debugging +- โœ… Direct access to logs +- โœ… Can use SQLite or PostgreSQL easily + +### Option 2: Docker Compose (Full Stack) + +```bash +# Uncomment the 'api' service in docker-compose.yml first + +# Build and start everything +docker-compose up --build + +# Or run in background +docker-compose up -d +``` + +**Benefits:** +- โœ… Production-like environment +- โœ… Isolated from host system +- โœ… Easy to share with team + +--- + +## ๐Ÿ› ๏ธ Troubleshooting + +### Port Already in Use + +**Error:** `bind: address already in use` + +**Solution:** +```bash +# Check what's using port 5432 +sudo lsof -i :5432 +# or +sudo netstat -tulpn | grep 5432 + +# Stop conflicting service +sudo systemctl stop postgresql # If system PostgreSQL is running + +# Change port in docker-compose.yml +ports: + - "5433:5432" # Use 5433 on host instead +``` + +### Can't Connect to Database + +**Check container is running:** +```bash +docker-compose ps +docker logs pd_postgres +``` + +**Check PostgreSQL is ready:** +```bash +docker exec pd_postgres pg_isready -U pd_admin +``` + +**Verify credentials:** +```bash +# Check environment variables +docker exec pd_postgres env | grep POSTGRES +``` + +### Database Data Corruption + +**Reset database (โš ๏ธ deletes all data):** +```bash +# Stop containers +docker-compose down + +# Remove volumes +docker volume rm database_postgres_data +# or +docker-compose down -v + +# Restart +docker-compose up -d +``` + +### Permission Errors + +**Fix volume permissions:** +```bash +# Docker +sudo chown -R $(whoami):$(whoami) ./storage ./logs + +# Podman (rootless) +# Usually no issues with rootless podman +``` + +--- + +## ๐Ÿ“Š Performance Tuning + +### PostgreSQL Configuration + +Edit `docker-compose.yml` to add PostgreSQL tuning: + +```yaml +postgres: + # ... other settings ... + command: > + postgres + -c shared_buffers=256MB + -c max_connections=100 + -c effective_cache_size=1GB + -c maintenance_work_mem=64MB + -c checkpoint_completion_target=0.9 +``` + +--- + +## ๐Ÿ” Production Considerations + +### DO NOT Use in Production As-Is + +This docker-compose.yml is for **local development only**. For production: + +1. โœ… Use strong passwords +2. โœ… Don't expose ports publicly +3. โœ… Set up proper backups +4. โœ… Use Docker secrets instead of environment variables +5. โœ… Set up SSL/TLS for PostgreSQL connections +6. โœ… Configure proper resource limits +7. โœ… Use separate PostgreSQL server (not container) + +--- + +## ๐Ÿ“š Additional Resources + +- **PostgreSQL Docs:** https://www.postgresql.org/docs/ +- **Docker Compose Docs:** https://docs.docker.com/compose/ +- **Adminer Docs:** https://www.adminer.org/ +- **Migration Guide:** See `POSTGRES_MIGRATION_PLAN.md` +- **Environment Config:** See `.env.example` + +--- + +**Last Updated:** 2025-11-07 +**For Help:** See `POSTGRES_MIGRATION_PLAN.md` or `MIGRATION_PROGRESS.md` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7b9aa00 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,64 @@ +version: '3.8' + +services: + # PostgreSQL Database + postgres: + image: postgres:17-alpine + restart: unless-stopped + container_name: pd_postgres + environment: + - POSTGRES_DB=${POSTGRES_DB:-pd_master} + - POSTGRES_USER=${POSTGRES_USER:-pd_admin} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-pd_dev_password} + - TZ=${TZ:-America/Chicago} + volumes: + - postgres_data:/var/lib/postgresql/data + - ./logs:/var/log/postgresql + ports: + - "${POSTGRES_PORT:-5432}:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-pd_admin} -d ${POSTGRES_DB:-pd_master}"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + + # Adminer - Database Admin UI + # Access at http://localhost:8080 + adminer: + image: adminer:latest + restart: unless-stopped + container_name: pd_adminer + ports: + - "8080:8080" + environment: + - ADMINER_DEFAULT_SERVER=pd_postgres + - TZ=${TZ:-America/New_York} + depends_on: + - postgres + + Paper Dynasty API (optional - can run locally with 'uvicorn app.main:app --reload') + Uncomment this section if you want to run the API in Docker + api: + build: . + restart: unless-stopped + container_name: pd_api + volumes: + - ./storage:/usr/src/app/storage + - ./logs:/usr/src/app/logs + ports: + - "8000:80" + environment: + - DATABASE_TYPE=postgresql + - POSTGRES_HOST=pd_postgres + - POSTGRES_DB=${POSTGRES_DB:-pd_master} + - POSTGRES_USER=${POSTGRES_USER:-pd_admin} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-pd_dev_password} + - LOG_LEVEL=${LOG_LEVEL:-INFO} + - API_TOKEN=${API_TOKEN:-dev_token} + depends_on: + - postgres + +volumes: + postgres_data: + driver: local