services: redis: image: redis:7-alpine ports: - "6379:6379" networks: - trivia-network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 backend: build: context: . dockerfile: Dockerfile.backend ports: - "5001:5001" environment: - FLASK_ENV=development - PORT=5001 - DATABASE_URI=sqlite:////app/backend/instance/trivia.db - CORS_ORIGINS=* - CELERY_BROKER_URL=redis://redis:6379/0 - CELERY_RESULT_BACKEND=redis://redis:6379/0 # OIDC/Authelia configuration - OIDC_ISSUER=${OIDC_ISSUER} - OIDC_CLIENT_ID=${OIDC_CLIENT_ID:-trivia-app} - OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET} - OIDC_REDIRECT_URI=${OIDC_REDIRECT_URI:-http://localhost:5001/api/auth/callback} - FRONTEND_URL=${FRONTEND_URL:-http://localhost:3000} - SESSION_COOKIE_SECURE=${SESSION_COOKIE_SECURE:-false} volumes: # Mount source code for hot reload - ./backend:/app/backend - ./main.py:/app/main.py - ./migrations:/app/migrations # Persist database - ./backend/instance:/app/backend/instance # Persist uploaded images - ./backend/static/images:/app/backend/static/images # Persist audio files - ./backend/static/audio:/app/backend/static/audio depends_on: redis: condition: service_healthy networks: - trivia-network healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:5001/api/health')"] interval: 10s timeout: 5s retries: 5 start_period: 10s celery-worker: build: context: . dockerfile: Dockerfile.backend command: uv run celery -A backend.celery_app worker --loglevel=info environment: - FLASK_ENV=development - CELERY_BROKER_URL=redis://redis:6379/0 - CELERY_RESULT_BACKEND=redis://redis:6379/0 - DATABASE_URI=sqlite:////app/backend/instance/trivia.db volumes: - ./backend:/app/backend - ./main.py:/app/main.py - ./backend/instance:/app/backend/instance - ./backend/static/audio:/app/backend/static/audio depends_on: redis: condition: service_healthy networks: - trivia-network celery-flower: build: context: . dockerfile: Dockerfile.backend command: uv run celery -A backend.celery_app flower --port=5555 ports: - "5555:5555" environment: - CELERY_BROKER_URL=redis://redis:6379/0 - CELERY_RESULT_BACKEND=redis://redis:6379/0 depends_on: - redis - celery-worker networks: - trivia-network frontend: build: context: . dockerfile: Dockerfile.frontend ports: - "3000:3000" environment: - VITE_BACKEND_URL=http://backend:5001 # OIDC configuration - VITE_OIDC_AUTHORITY=${OIDC_ISSUER} - VITE_OIDC_CLIENT_ID=${OIDC_CLIENT_ID:-trivia-app} volumes: # Mount source code for hot reload - ./frontend/frontend/src:/app/src - ./frontend/frontend/public:/app/public - ./frontend/frontend/index.html:/app/index.html - ./frontend/frontend/vite.config.js:/app/vite.config.js:ro - ./frontend/frontend/eslint.config.js:/app/eslint.config.js # Use named volume for node_modules to avoid conflicts - frontend-node-modules:/app/node_modules depends_on: backend: condition: service_healthy networks: - trivia-network networks: trivia-network: driver: bridge volumes: frontend-node-modules: