version: "3.8" services: # PostgreSQL - MTG Online App Database postgres: image: postgres:16-alpine container_name: mtgonline_postgres restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-mtgonline} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mtgonline_pass} POSTGRES_DB: ${POSTGRES_DB:-mtgonline} POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C" ports: - "${POSTGRES_PORT:-5432}:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/01-init.sql networks: - mtg_network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-mtgonline}"] interval: 10s timeout: 5s retries: 5 start_period: 30s # PostgreSQL - MTG Data Database postgres-mtgdata: image: postgres:16-alpine container_name: mtgonline_postgres_mtgdata restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-mtgonline} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mtgonline_pass} POSTGRES_DB: ${MTGDATA_DB:-mtgdata} POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C" ports: - "${MTGDATA_PORT:-5433}:5432" volumes: - postgres_mtgdata_data:/var/lib/postgresql/data - ./scripts/init-mtgdata.sql:/docker-entrypoint-initdb.d/01-init.sql networks: - mtg_network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-mtgonline}"] interval: 10s timeout: 5s retries: 5 start_period: 30s # Redis cache redis: image: redis:7-alpine container_name: mtgonline_redis restart: unless-stopped ports: - "${REDIS_PORT:-6379}:6379" networks: - mtg_network healthcheck: test: ["CMD-SHELL", "redis-cli ping | grep PONG"] interval: 10s timeout: 5s retries: 5 start_period: 5s # Backend API backend: build: context: ./backend dockerfile: Dockerfile container_name: mtgonline_backend restart: unless-stopped depends_on: postgres: condition: service_healthy postgres-mtgdata: condition: service_healthy redis: condition: service_healthy environment: - DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://mtgonline:mtgonline_pass@postgres:5432/mtgonline} - MTG_DATABASE_URL=${MTG_DATABASE_URL:-postgresql+asyncpg://mtgonline:mtgonline_pass@postgres-mtgdata:5432/mtgdata} - JWT_SECRET_KEY=${JWT_SECRET_KEY:-change-me-in-production} - JWT_ALGORITHM=${JWT_ALGORITHM:-HS256} - JWT_ACCESS_TOKEN_EXPIRE_MINUTES=${JWT_ACCESS_TOKEN_EXPIRE_MINUTES:-60} - JWT_REFRESH_TOKEN_EXPIRE_DAYS=${JWT_REFRESH_TOKEN_EXPIRE_DAYS:-7} - REDIS_URL=${REDIS_URL:-redis://redis:6379/0} - CORS_ORIGINS=${CORS_ORIGINS:-["http://localhost:3000","http://localhost:8000"]} - APP_NAME=${APP_NAME:-MTG Online} - APP_VERSION=${APP_VERSION:-0.2.0} - DEBUG=${DEBUG:-False} - SECRET_KEY=${SECRET_KEY:-change-me-in-production} - MTG_REFRESH_INTERVAL_DAYS=${MTG_REFRESH_INTERVAL_DAYS:-7} - DATA_DIR=${DATA_DIR:-/app/data} - UPLOAD_DIR=${UPLOAD_DIR:-/app/uploads} - LOG_LEVEL=${LOG_LEVEL:-INFO} - LOG_FORMAT=${LOG_FORMAT:-json} - SMTP_HOST=${SMTP_HOST:-} - SMTP_PORT=${SMTP_PORT:-587} - SMTP_USER=${SMTP_USER:-} - SMTP_PASSWORD=${SMTP_PASSWORD:-} - EMAIL_FROM=${EMAIL_FROM:-} - BCRYPT_ROUNDS=${BCRYPT_ROUNDS:-12} - MAX_LOGIN_ATTEMPTS=${MAX_LOGIN_ATTEMPTS:-5} - LOGIN_BLOCK_MINUTES=${LOGIN_BLOCK_MINUTES:-15} ports: - "${BACKEND_PORT:-5555}:8000" volumes: - mtg_data:/app/data - mtg_uploads:/app/uploads - mtg_logs:/app/logs networks: - mtg_network healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"] interval: 30s timeout: 30s retries: 3 start_period: 600s # 10 minutes for initial data download # Weekly database refresh (runs on a schedule) mtg-refresh: build: context: ./backend dockerfile: Dockerfile container_name: mtgonline_refresh restart: "no" depends_on: postgres: condition: service_healthy postgres-mtgdata: condition: service_healthy environment: - DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://mtgonline:mtgonline_pass@postgres:5432/mtgonline} - MTG_DATABASE_URL=${MTG_DATABASE_URL:-postgresql+asyncpg://mtgonline:mtgonline_pass@postgres-mtgdata:5432/mtgdata} - DATA_DIR=${DATA_DIR:-/app/data} - MTG_REFRESH_INTERVAL_DAYS=${MTG_REFRESH_INTERVAL_DAYS:-7} volumes: - mtg_data:/app/data command: ["python", "-m", "app.scripts.refresh_mtg"] networks: - mtg_network volumes: postgres_data: driver: local postgres_mtgdata_data: driver: local mtg_data: driver: local mtg_uploads: driver: local mtg_logs: driver: local networks: mtg_network: driver: bridge