diff --git a/backend/.env.docker b/backend/.env.docker new file mode 100644 index 0000000..e2a7640 --- /dev/null +++ b/backend/.env.docker @@ -0,0 +1,83 @@ +# MTG Online - Docker Deployment Environment Configuration +# ============================================================ +# Copy this file to .env and customize for your deployment. +# +# SECURITY NOTES: +# - Change all passwords before deploying to production +# - Use strong, unique passwords for each database +# - Rotate SECRET_KEY and JWT_SECRET_KEY regularly +# - Never commit .env files to version control + +# ============================================================================= +# DATABASE CONFIGURATION +# ============================================================================= +# Three PostgreSQL databases are used: +# 1. mtgo_platform - Main platform data (users, decks, collections) +# 2. mtgdata - MTG card data (cards, sets, prices) +# 3. mtgo_mirror - Mirror/sync data for offline access + +MTG_DATABASE_URL=postgresql+asyncpg://postgres:postgres@postgres_mtgdata:5432/mtgdata +MTG_PLATFORM_DATABASE_URL=postgresql+asyncpg://postgres:postgres@postgres_platform:5432/mtgo_platform +MTG_MIRROR_DATABASE_URL=postgresql+asyncpg://postgres:postgres@postgres_mirror:5432/mtgo_mirror + +# ============================================================================= +# BACKEND SERVER +# ============================================================================= +# The backend runs on port 8000 inside the container, mapped to 8990 externally +MTG_BACKEND_URL=http://localhost:8990 + +# ============================================================================= +# MTGJSON DATA +# ============================================================================= +# Directory for storing MTGJSON data files +MTGJSON_DATA_DIR=/app/data +MTGJSON_URL=https://mtgjson.com/api/v5/ + +# ============================================================================= +# INTERACTION PIPELINE +# ============================================================================= +# Minimum confidence score for interaction detection +MTG_INTERACTION_MIN_CONFIDENCE=0.5 +# Batch size for interaction processing +MTG_INTERACTION_BATCH_SIZE=1000 +# Enable review queue for low-confidence interactions +MTG_INTERACTION_REVIEW_QUEUE=true + +# ============================================================================= +# LOGGING +# ============================================================================= +# Log level: DEBUG, INFO, WARNING, ERROR, CRITICAL +MTG_LOG_LEVEL=INFO +# Log format: json or text +MTG_LOG_FORMAT=json + +# ============================================================================= +# REDIS +# ============================================================================= +# Redis URL for caching and session management +REDIS_URL=redis://redis:6379/0 + +# ============================================================================= +# SECURITY - CHANGE THESE IN PRODUCTION +# ============================================================================= +SECRET_KEY=change-this-secret-key-in-production +JWT_SECRET_KEY=change-this-jwt-secret-key-in-production + +# ============================================================================= +# VOLUME PATHS +# ============================================================================= +DATA_DIR=/app/data +UPLOAD_DIR=/app/uploads + +# ============================================================================= +# DEPLOYMENT CHECKLIST +# ============================================================================= +# Before deploying: +# [ ] Change all database passwords +# [ ] Change SECRET_KEY and JWT_SECRET_KEY +# [ ] Set MTG_LOG_LEVEL to WARNING or ERROR in production +# [ ] Review health check intervals +# [ ] Configure reverse proxy (nginx/caddy) for HTTPS +# [ ] Set up log rotation and monitoring +# [ ] Test migrations with new database credentials +# [ ] Verify all three databases are accessible diff --git a/backend/Dockerfile b/backend/Dockerfile index 6efcf06..b86df3d 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -45,9 +45,17 @@ RUN chmod +x /app/scripts/*.py COPY --chown=appuser:appuser .env.example ./.env.example COPY --chown=appuser:appuser pyproject.toml ./ -ENV PYTHONPATH=/app +# Python environment variables for proper logging ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONPATH=/app + +# Logging configuration +ENV MTG_LOG_LEVEL=INFO +ENV MTG_LOG_FORMAT=json + +# Create logging directory with proper permissions +RUN mkdir -p /app/logs && chown appuser:appuser /app/logs HEALTHCHECK --interval=30s --timeout=20s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8000/health || exit 1 diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index cd4ad15..f7e5679 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -1,18 +1,25 @@ -version: '3.8' - services: backend: build: context: . dockerfile: Dockerfile ports: - - "8000:8000" + - "8990:8000" environment: - - DATABASE_URL=postgresql+asyncpg://mtgo_user:mtgo_password@postgres:5432/mtgo_platform - - MTG_DATABASE_URL=postgresql+asyncpg://mtgo_user:mtgo_password@postgres_mtgdata:5432/mtg_data + - MTG_DATABASE_URL=postgresql+asyncpg://postgres:postgres@postgres_mtgdata:5432/mtgdata + - MTG_PLATFORM_DATABASE_URL=postgresql+asyncpg://postgres:postgres@postgres_platform:5432/mtgo_platform + - MTG_MIRROR_DATABASE_URL=postgresql+asyncpg://postgres:postgres@postgres_mirror:5432/mtgo_mirror + - MTG_BACKEND_URL=http://localhost:8990 + - MTGJSON_DATA_DIR=/app/data + - MTGJSON_URL=https://mtgjson.com/api/v5/ + - MTG_INTERACTION_MIN_CONFIDENCE=0.5 + - MTG_INTERACTION_BATCH_SIZE=1000 + - MTG_INTERACTION_REVIEW_QUEUE=true + - MTG_LOG_LEVEL=INFO + - MTG_LOG_FORMAT=json - REDIS_URL=redis://redis:6379/0 - - SECRET_KEY=your-secret-key-change-in-production - - JWT_SECRET_KEY=your-jwt-secret-key-change-in-production + - SECRET_KEY=change-this-secret-key-in-production + - JWT_SECRET_KEY=change-this-jwt-secret-key-in-production - DATA_DIR=/app/data - UPLOAD_DIR=/app/uploads volumes: @@ -20,10 +27,12 @@ services: - mtg_uploads:/app/uploads - mtg_logs:/app/logs depends_on: - postgres: + postgres_platform: condition: service_healthy postgres_mtgdata: condition: service_healthy + postgres_mirror: + condition: service_healthy redis: condition: service_healthy healthcheck: @@ -32,60 +41,101 @@ services: timeout: 20s retries: 3 start_period: 40s + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + tag: "{{.Name}}" networks: - mtgonline_network - postgres: + postgres_platform: image: postgres:16-alpine environment: - - POSTGRES_USER=mtgo_user - - POSTGRES_PASSWORD=mtgo_password + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres - POSTGRES_DB=mtgo_platform volumes: - - postgres_data:/var/lib/postgresql/data - ports: - - "5432:5432" + - postgres_platform_data:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -U mtgo_user -d mtgo_platform"] + test: ["CMD-SHELL", "pg_isready -U postgres -d mtgo_platform"] interval: 10s timeout: 5s retries: 5 + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + tag: "{{.Name}}" networks: - mtgonline_network postgres_mtgdata: image: postgres:16-alpine environment: - - POSTGRES_USER=mtgo_user - - POSTGRES_PASSWORD=mtgo_password - - POSTGRES_DB=mtg_data + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + - POSTGRES_DB=mtgdata volumes: - - postgres_mtgdata:/var/lib/postgresql/data - ports: - - "5433:5432" + - postgres_mtgdata_data:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -U mtgo_user -d mtg_data"] + test: ["CMD-SHELL", "pg_isready -U postgres -d mtgdata"] interval: 10s timeout: 5s retries: 5 + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + tag: "{{.Name}}" + networks: + - mtgonline_network + + postgres_mirror: + image: postgres:16-alpine + environment: + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + - POSTGRES_DB=mtgo_mirror + volumes: + - postgres_mirror_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres -d mtgo_mirror"] + interval: 10s + timeout: 5s + retries: 5 + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + tag: "{{.Name}}" networks: - mtgonline_network redis: image: redis:7-alpine - ports: - - "6379:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + tag: "{{.Name}}" networks: - mtgonline_network volumes: - postgres_data: - postgres_mtgdata: + postgres_platform_data: + postgres_mtgdata_data: + postgres_mirror_data: mtg_data: mtg_uploads: mtg_logs: