services: # ─── MongoDB ────────────────────────────────────────────────────── mongo: image: mongo:7 restart: unless-stopped ports: - "127.0.0.1:27017:27017" volumes: - mongo-data:/data/db healthcheck: test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"] interval: 10s timeout: 5s retries: 5 # ─── Python / Quart backend ─────────────────────────────────────── backend: build: ./backend restart: unless-stopped env_file: - ./backend/.env environment: MONGO_URI: mongodb://mongo:27017/cohorta_db volumes: - ./backend/uploads:/app/uploads - ./backend/temp:/app/temp depends_on: mongo: condition: service_healthy labels: - "traefik.enable=true" # REST API — higher priority than the SPA catch-all - "traefik.http.routers.cohorta-api.rule=Host(`cohorta.ai-impress.com`) && PathPrefix(`/api`)" - "traefik.http.routers.cohorta-api.entrypoints=websecure" - "traefik.http.routers.cohorta-api.tls.certresolver=cloudflare" - "traefik.http.routers.cohorta-api.priority=20" - "traefik.http.services.cohorta-api.loadbalancer.server.port=5137" # Socket.IO — also high priority - "traefik.http.routers.cohorta-ws.rule=Host(`cohorta.ai-impress.com`) && PathPrefix(`/socket.io`)" - "traefik.http.routers.cohorta-ws.entrypoints=websecure" - "traefik.http.routers.cohorta-ws.tls.certresolver=cloudflare" - "traefik.http.routers.cohorta-ws.priority=20" - "traefik.http.routers.cohorta-ws.service=cohorta-api" # ─── React SPA (nginx-alpine) ───────────────────────────────────── frontend: build: context: . dockerfile: Dockerfile.frontend restart: unless-stopped depends_on: - backend labels: - "traefik.enable=true" - "traefik.http.routers.cohorta.rule=Host(`cohorta.ai-impress.com`)" - "traefik.http.routers.cohorta.entrypoints=websecure" - "traefik.http.routers.cohorta.tls.certresolver=cloudflare" - "traefik.http.routers.cohorta.priority=1" - "traefik.http.services.cohorta.loadbalancer.server.port=80" volumes: mongo-data: networks: default: name: traefik-public external: true