name: east-guilan

services:
  traefik:
    image: traefik:v2.11
    entrypoint: ["/bin/sh", "/traefik-entrypoint.sh"]
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --entrypoints.web.http.redirections.entryPoint.to=websecure
      - --entrypoints.web.http.redirections.entryPoint.scheme=https
      - --certificatesresolvers.le.acme.email=${LETSENCRYPT_EMAIL}
      - --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
      - --certificatesresolvers.le.acme.httpchallenge=true
      - --certificatesresolvers.le.acme.httpchallenge.entrypoint=web

      # 🔹 Enable Prometheus metrics
      - --metrics.prometheus=true
      - --metrics.prometheus.addEntryPointsLabels=true
      - --metrics.prometheus.addRoutersLabels=true
      - --metrics.prometheus.addServicesLabels=true

      # 🔹 Expose metrics on a separate entrypoint (port 8082)
      - --entrypoints.metrics.address=:8082
      - --metrics.prometheus.entryPoint=metrics

      # (optional) dashboard if you want it later:
      - --api.dashboard=true

      # Route /metrics on api.east-guilan-ce.ir to web:8000
      - traefik.http.routers.metrics.rule=Host(`api.east-guilan-ce.ir`) && Path(`/metrics`)
      - traefik.http.routers.metrics.entrypoints=websecure
      - traefik.http.routers.metrics.tls.certresolver=le
      - traefik.http.services.metrics.loadbalancer.server.port=8000

    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./traefik/entrypoint.sh:/traefik-entrypoint.sh:ro
      - ./certs:/certs:ro
      - traefik_letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME} -h 127.0.0.1"]
      interval: 10s
      timeout: 5s
      retries: 10
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    command: ["redis-server", "--appendonly", "yes", "--requirepass", "${REDIS_PASSWORD}"]
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "PING"]
      interval: 10s
      timeout: 5s
      retries: 10
    volumes:
      - redis_data:/data

  web:
    build:
      context: ./backend
      dockerfile: Dockerfile
    env_file: .env
    environment:
      DJANGO_SETTINGS_MODULE: ${DJANGO_SETTINGS_MODULE}
      REDIS_URL: ${REDIS_URL}
      PROMETHEUS_MULTIPROC_DIR: /tmp/prometheus
    tmpfs:
      - /tmp/prometheus  
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    volumes:
      - django_static:/app/staticfiles
      - django_media:/app/media
    command: >
      gunicorn config.wsgi:application
      --bind 0.0.0.0:8000
      --workers=${GUNICORN_WORKERS:-3}
      --threads=${GUNICORN_THREADS:-2}
      --timeout=${GUNICORN_TIMEOUT:-120}
    labels:
      - traefik.enable=true

      - traefik.http.routers.api.rule=Host(`api.east-guilan-ce.ir`) && PathPrefix(`/api`)
      - traefik.http.routers.api.entrypoints=websecure
      - traefik.http.routers.api.tls.certresolver=le
      - traefik.http.routers.api.priority=10
      - traefik.http.services.api.loadbalancer.server.port=8000

      - traefik.http.routers.admin.rule=Host(`api.east-guilan-ce.ir`) && PathPrefix(`/admin`)
      - traefik.http.routers.admin.entrypoints=websecure
      - traefik.http.routers.admin.tls.certresolver=le
      - traefik.http.routers.admin.priority=10

  worker:
    build:
      context: ./backend
      dockerfile: Dockerfile
    env_file: .env
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    command: celery -A config.services.celery worker --loglevel=INFO
    volumes:
      - django_media:/app/media

  beat:
    build:
      context: ./backend
      dockerfile: Dockerfile
    env_file: .env
    depends_on:
      - worker
    command: celery -A config.services.celery beat --loglevel=INFO
    volumes:
      - django_media:/app/media
    
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
      args:
        NEXT_PUBLIC_API_BASE: https://api.east-guilan-ce.ir
    labels:
      - traefik.enable=true
      - traefik.http.routers.frontend.rule=Host(`${NEXT_HOST}`)
      - traefik.http.routers.frontend.entrypoints=websecure
      - traefik.http.routers.frontend.tls.certresolver=le
      - traefik.http.services.frontend.loadbalancer.server.port=80

  static:
      image: nginx:1.27-alpine
      volumes:
        - ./nginx-static.conf:/etc/nginx/conf.d/default.conf:ro
        - django_static:/var/www/static:ro
        - django_media:/var/www/media:ro
      labels:
        - traefik.enable=true
        # higher priority so /static & /media never reach backend
        - traefik.http.routers.static.rule=Host(`api.east-guilan-ce.ir`) && PathPrefix(`/static`)
        - traefik.http.routers.static.entrypoints=websecure
        - traefik.http.routers.static.tls.certresolver=le
        - traefik.http.routers.static.priority=20
        - traefik.http.services.static.loadbalancer.server.port=80

        - traefik.http.routers.media.rule=Host(`api.east-guilan-ce.ir`) && PathPrefix(`/media`)
        - traefik.http.routers.media.entrypoints=websecure
        - traefik.http.routers.media.tls.certresolver=le
        - traefik.http.routers.media.priority=20

  uptime:
    image: louislam/uptime-kuma:1
    restart: unless-stopped
    volumes: ["./data/uptime:/app/data"]
    labels:
      - traefik.enable=true
      - traefik.http.routers.kuma.rule=Host(`uptime.east-guilan-ce.ir`)
      - traefik.http.routers.kuma.entrypoints=websecure
      - traefik.http.routers.kuma.tls.certresolver=le
      - traefik.http.services.kuma.loadbalancer.server.port=3001

  node_exporter:
    image: prom/node-exporter:v1.9.1
    restart: unless-stopped
    ports: ["9100:9100"]
    volumes:
      - /:/host:ro,rslave
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /run/udev:/host/run/udev:ro
    command:
      - --path.rootfs=/host
      - --path.procfs=/host/proc
      - --path.sysfs=/host/sys
      - --path.udev.data=/host/run/udev/data

  # postgres_exporter:
  #   image: quay.io/prometheuscommunity/postgres-exporter:v0.15.0
  #   restart: unless-stopped
  #   environment:
  #     - DATA_SOURCE_NAME=postgresql://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}?sslmode=disable
  #   depends_on:
  #     db:
  #       condition: service_healthy

  redis_exporter:
    image: oliver006/redis_exporter:v1.62.0
    restart: unless-stopped
    command:
      - '--redis.addr=redis://redis:6379'
      - '--redis.password=${REDIS_PASSWORD}'

  grafana:
    image: grafana/grafana
    restart: unless-stopped
    labels:
      - traefik.enable=true
      - traefik.http.routers.grafana.rule=Host(`grafana.east-guilan-ce.ir`)
      - traefik.http.routers.grafana.entrypoints=websecure
      - traefik.http.routers.grafana.tls.certresolver=le
      - traefik.http.services.grafana.loadbalancer.server.port=3000
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana-datasources.yml:/etc/grafana/provisioning/datasources/datasource.yml:ro
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=changeMeNow
      - GF_USERS_ALLOW_SIGN_UP=false

  alertmanager:
    image: prom/alertmanager
    restart: unless-stopped
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
    command: --config.file=/etc/alertmanager/alertmanager.yml

  prometheus:
    image: prom/prometheus
    volumes:
      - prometheus_data:/prometheus
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
    restart: unless-stopped
    labels:
      - traefik.enable=true
      - traefik.http.routers.prom.rule=Host(`prometheus.east-guilan-ce.ir`)
      - traefik.http.routers.prom.entrypoints=websecure
      - traefik.http.routers.prom.tls.certresolver=le
      - traefik.http.services.prom.loadbalancer.server.port=9090

volumes:
  traefik_letsencrypt:
  postgres_data:
  redis_data:
  django_media:
  django_static:
  prometheus_data:
  grafana_data:
