services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    restart: unless-stopped

  chat-postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${CHAT_POSTGRES_DB}
      POSTGRES_USER: ${CHAT_POSTGRES_USER}
      POSTGRES_PASSWORD: ${CHAT_POSTGRES_PASSWORD}
    volumes:
      - chat_postgres_data:/var/lib/postgresql/data

  postgres-backup:
    image: postgres:16-alpine
    restart: unless-stopped
    depends_on:
      - postgres
      - chat-postgres
    environment:
      TZ: ${BACKUP_TZ:-Europe/Moscow}
      BACKUP_DIR: /backups
      BACKUP_INTERVAL_SECONDS: ${BACKUP_INTERVAL_SECONDS:-86400}
      BACKUP_RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-7}
      BACKUP_GZIP_LEVEL: ${BACKUP_GZIP_LEVEL:-6}
      BACKUP_INCLUDE_CHAT_DB: ${BACKUP_INCLUDE_CHAT_DB:-true}
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      CHAT_POSTGRES_HOST: chat-postgres
      CHAT_POSTGRES_PORT: 5432
      CHAT_POSTGRES_DB: ${CHAT_POSTGRES_DB}
      CHAT_POSTGRES_USER: ${CHAT_POSTGRES_USER}
      CHAT_POSTGRES_PASSWORD: ${CHAT_POSTGRES_PASSWORD}
    command: ["/bin/sh", "/scripts/pg-backup.sh"]
    volumes:
      - ./scripts/pg-backup.sh:/scripts/pg-backup.sh:ro
      - ./backups:/backups

  adminer:
    image: adminer:5
    restart: unless-stopped
    depends_on:
      - postgres
    expose:
      - "8080"
    networks:
      - default
      - proxy
    labels:
      - traefik.enable=true
      - traefik.docker.network=proxy
      - traefik.http.routers.alpinbet-adminer.rule=Host(`db.antigol.ru`)
      - traefik.http.routers.alpinbet-adminer.entrypoints=websecure
      - traefik.http.routers.alpinbet-adminer.tls.certresolver=letsencrypt
      - traefik.http.services.alpinbet-adminer.loadbalancer.server.port=8080

  dockmon:
    image: darthnorse/dockmon:latest
    restart: unless-stopped
    environment:
      TZ: Europe/Moscow
      PYTHONPATH: /app/backend
      PYTHONUNBUFFERED: 1
      REVERSE_PROXY_MODE: "true"
      DOCKMON_EXTERNAL_URL: https://monitor.antigol.ru
      DOCKMON_CORS_ORIGINS: https://monitor.antigol.ru
    expose:
      - "80"
    volumes:
      - dockmon_data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - default
      - proxy
    labels:
      - traefik.enable=true
      - traefik.docker.network=proxy
      - traefik.http.routers.alpinbet-dockmon.rule=Host(`monitor.antigol.ru`)
      - traefik.http.routers.alpinbet-dockmon.entrypoints=websecure
      - traefik.http.routers.alpinbet-dockmon.tls.certresolver=letsencrypt
      - traefik.http.services.alpinbet-dockmon.loadbalancer.server.port=80

  backend:
    build:
      context: ./backend
    restart: unless-stopped
    depends_on:
      - postgres
      - redis
    command: npm run start:api:with-db-url
    environment:
      REDIS_URL: redis://redis:6379
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_SCHEMA: public
      PORT: 4000
      JWT_SECRET: ${JWT_SECRET}
      JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d}
      CORS_ORIGIN: ${CORS_ORIGIN}
      APP_PUBLIC_URL: ${APP_PUBLIC_URL}
      SMTP_HOST: ${SMTP_HOST:-}
      SMTP_PORT: ${SMTP_PORT:-587}
      SMTP_SECURE: ${SMTP_SECURE:-false}
      SMTP_USER: ${SMTP_USER:-}
      SMTP_PASSWORD: ${SMTP_PASSWORD:-}
      SMTP_FROM_EMAIL: ${SMTP_FROM_EMAIL:-}
      SMTP_FROM_NAME: ${SMTP_FROM_NAME:-Alpinbet}
      PASSWORD_RESET_TTL_MINUTES: ${PASSWORD_RESET_TTL_MINUTES:-60}
      APP_LATEST_VERSION: ${APP_LATEST_VERSION:-}
      APP_MIN_SUPPORTED_VERSION: ${APP_MIN_SUPPORTED_VERSION:-}
      APP_UPDATE_URL: ${APP_UPDATE_URL:-}
      APP_UPDATE_MESSAGE: ${APP_UPDATE_MESSAGE:-}
      VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY:-}
      VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY:-}
      VAPID_SUBJECT: ${VAPID_SUBJECT:-mailto:admin@example.com}
      FIREBASE_PROJECT_ID: ${FIREBASE_PROJECT_ID:-}
      FIREBASE_CLIENT_EMAIL: ${FIREBASE_CLIENT_EMAIL:-}
      FIREBASE_PRIVATE_KEY: ${FIREBASE_PRIVATE_KEY:-}
      FIREBASE_SERVICE_ACCOUNT_JSON: ${FIREBASE_SERVICE_ACCOUNT_JSON:-}
      SETTLEMENT_INTERVAL_MS: ${SETTLEMENT_INTERVAL_MS:-60000}
      PARSER_INTERNAL_SECRET: ${PARSER_INTERNAL_SECRET}
      VAPID_STATE_DIR: /app/runtime
    expose:
      - "4000"
    volumes:
      - backend_runtime:/app/runtime
    networks:
      - default
      - proxy
    labels:
      - traefik.enable=true
      - traefik.docker.network=proxy
      - traefik.http.routers.alpinbet-backend.rule=Host(`api.antigol.ru`)
      - traefik.http.routers.alpinbet-backend.entrypoints=websecure
      - traefik.http.routers.alpinbet-backend.tls.certresolver=letsencrypt
      - traefik.http.services.alpinbet-backend.loadbalancer.server.port=4000

  backend-signals-worker:
    build:
      context: ./backend
    restart: unless-stopped
    depends_on:
      - postgres
      - redis
    command: npm run start:signals-worker:with-db-url
    environment:
      REDIS_URL: redis://redis:6379
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_SCHEMA: public
      PORT: 4000
      JWT_SECRET: ${JWT_SECRET}
      JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d}
      CORS_ORIGIN: ${CORS_ORIGIN}
      APP_PUBLIC_URL: ${APP_PUBLIC_URL}
      SMTP_HOST: ${SMTP_HOST:-}
      SMTP_PORT: ${SMTP_PORT:-587}
      SMTP_SECURE: ${SMTP_SECURE:-false}
      SMTP_USER: ${SMTP_USER:-}
      SMTP_PASSWORD: ${SMTP_PASSWORD:-}
      SMTP_FROM_EMAIL: ${SMTP_FROM_EMAIL:-}
      SMTP_FROM_NAME: ${SMTP_FROM_NAME:-Alpinbet}
      PASSWORD_RESET_TTL_MINUTES: ${PASSWORD_RESET_TTL_MINUTES:-60}
      APP_LATEST_VERSION: ${APP_LATEST_VERSION:-}
      APP_MIN_SUPPORTED_VERSION: ${APP_MIN_SUPPORTED_VERSION:-}
      APP_UPDATE_URL: ${APP_UPDATE_URL:-}
      APP_UPDATE_MESSAGE: ${APP_UPDATE_MESSAGE:-}
      VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY:-}
      VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY:-}
      VAPID_SUBJECT: ${VAPID_SUBJECT:-mailto:admin@example.com}
      FIREBASE_PROJECT_ID: ${FIREBASE_PROJECT_ID:-}
      FIREBASE_CLIENT_EMAIL: ${FIREBASE_CLIENT_EMAIL:-}
      FIREBASE_PRIVATE_KEY: ${FIREBASE_PRIVATE_KEY:-}
      FIREBASE_SERVICE_ACCOUNT_JSON: ${FIREBASE_SERVICE_ACCOUNT_JSON:-}
      SETTLEMENT_INTERVAL_MS: ${SETTLEMENT_INTERVAL_MS:-60000}
      PARSER_INTERNAL_SECRET: ${PARSER_INTERNAL_SECRET}
      VAPID_STATE_DIR: /app/runtime
    volumes:
      - backend_runtime:/app/runtime

  backend-push-worker:
    build:
      context: ./backend
    restart: unless-stopped
    depends_on:
      - postgres
      - redis
    command: npm run start:push-worker:with-db-url
    environment:
      REDIS_URL: redis://redis:6379
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_SCHEMA: public
      PORT: 4000
      JWT_SECRET: ${JWT_SECRET}
      JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d}
      CORS_ORIGIN: ${CORS_ORIGIN}
      APP_PUBLIC_URL: ${APP_PUBLIC_URL}
      SMTP_HOST: ${SMTP_HOST:-}
      SMTP_PORT: ${SMTP_PORT:-587}
      SMTP_SECURE: ${SMTP_SECURE:-false}
      SMTP_USER: ${SMTP_USER:-}
      SMTP_PASSWORD: ${SMTP_PASSWORD:-}
      SMTP_FROM_EMAIL: ${SMTP_FROM_EMAIL:-}
      SMTP_FROM_NAME: ${SMTP_FROM_NAME:-Alpinbet}
      PASSWORD_RESET_TTL_MINUTES: ${PASSWORD_RESET_TTL_MINUTES:-60}
      APP_LATEST_VERSION: ${APP_LATEST_VERSION:-}
      APP_MIN_SUPPORTED_VERSION: ${APP_MIN_SUPPORTED_VERSION:-}
      APP_UPDATE_URL: ${APP_UPDATE_URL:-}
      APP_UPDATE_MESSAGE: ${APP_UPDATE_MESSAGE:-}
      VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY:-}
      VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY:-}
      VAPID_SUBJECT: ${VAPID_SUBJECT:-mailto:admin@example.com}
      FIREBASE_PROJECT_ID: ${FIREBASE_PROJECT_ID:-}
      FIREBASE_CLIENT_EMAIL: ${FIREBASE_CLIENT_EMAIL:-}
      FIREBASE_PRIVATE_KEY: ${FIREBASE_PRIVATE_KEY:-}
      FIREBASE_SERVICE_ACCOUNT_JSON: ${FIREBASE_SERVICE_ACCOUNT_JSON:-}
      SETTLEMENT_INTERVAL_MS: ${SETTLEMENT_INTERVAL_MS:-60000}
      PARSER_INTERNAL_SECRET: ${PARSER_INTERNAL_SECRET}
      VAPID_STATE_DIR: /app/runtime
    volumes:
      - backend_runtime:/app/runtime

  chat-service:
    build:
      context: ./chat-service
    restart: unless-stopped
    depends_on:
      - chat-postgres
    command: npm run start:with-db-url
    environment:
      CHAT_POSTGRES_HOST: chat-postgres
      CHAT_POSTGRES_PORT: 5432
      CHAT_POSTGRES_DB: ${CHAT_POSTGRES_DB}
      CHAT_POSTGRES_USER: ${CHAT_POSTGRES_USER}
      CHAT_POSTGRES_PASSWORD: ${CHAT_POSTGRES_PASSWORD}
      CHAT_POSTGRES_SCHEMA: public
      PORT: 4050
      JWT_SECRET: ${JWT_SECRET}
      CORS_ORIGIN: ${CORS_ORIGIN}
    expose:
      - "4050"
    networks:
      - default
      - proxy
    labels:
      - traefik.enable=true
      - traefik.docker.network=proxy
      - traefik.http.routers.alpinbet-chat.rule=Host(`chat.antigol.ru`)
      - traefik.http.routers.alpinbet-chat.entrypoints=websecure
      - traefik.http.routers.alpinbet-chat.tls.certresolver=letsencrypt
      - traefik.http.services.alpinbet-chat.loadbalancer.server.port=4050

  parser:
    build:
      context: .
      dockerfile: ./parser/Dockerfile
    depends_on:
      - redis
      - forecast-ocr
    command: npm run start
    env_file:
      - ./parser/.env
    environment:
      REDIS_URL: redis://redis:6379
      BACKEND_INTERNAL_URL: http://backend:4000
      PARSER_INTERNAL_SECRET: ${PARSER_INTERNAL_SECRET}
      FORECAST_OCR_URL: http://forecast-ocr:4010
    volumes:
      - ./parser/data:/app/parser/data
    restart: unless-stopped

  forecast-ocr:
    build:
      context: ./forecast-ocr-service
    restart: unless-stopped
    expose:
      - "4010"

  frontend:
    build:
      context: ./frontend
    depends_on:
      - backend
      - chat-service
    environment:
      NUXT_PUBLIC_API_BASE: ${NUXT_PUBLIC_API_BASE}
      NUXT_PUBLIC_CHAT_API_BASE: ${NUXT_PUBLIC_CHAT_API_BASE}
      NUXT_API_BASE_INTERNAL: http://backend:4000
    expose:
      - "3000"
    networks:
      - default
      - proxy
    labels:
      - traefik.enable=true
      - traefik.docker.network=proxy
      - traefik.http.routers.alpinbet-frontend.rule=Host(`antigol.ru`)
      - traefik.http.routers.alpinbet-frontend.entrypoints=websecure
      - traefik.http.routers.alpinbet-frontend.tls.certresolver=letsencrypt
      - traefik.http.services.alpinbet-frontend.loadbalancer.server.port=3000

  downloads:
    build:
      context: ./downloads-service
    restart: unless-stopped
    expose:
      - "8080"
    volumes:
      - ./downloads:/app/downloads:ro
    networks:
      - default
      - proxy
    labels:
      - traefik.enable=true
      - traefik.docker.network=proxy
      - traefik.http.routers.alpinbet-downloads.rule=Host(`files.antigol.ru`)
      - traefik.http.routers.alpinbet-downloads.entrypoints=websecure
      - traefik.http.routers.alpinbet-downloads.tls.certresolver=letsencrypt
      - traefik.http.services.alpinbet-downloads.loadbalancer.server.port=8080

volumes:
  postgres_data:
  chat_postgres_data:
  backend_runtime:
  dockmon_data:

networks:
  proxy:
    external: true
