# `docker compose up` поднимает кластер целиком: redis, node-a, node-b за # nginx-балансировщиком на 8080, плюс Prometheus на 9090 и Grafana на 3000. # # Маскирование детерминировано и работает на любом узле, а вот обратный шаг # требует общего состояния — отсюда общий Redis между node-a и node-b. # # Лимиты CPU/RAM: сервер — 4 vCPU. Без лимитов node-a/node-b/prometheus/grafana # под нагрузкой отжимали CPU у Redis, тот не укладывался в таймаут команд, узлы # теряли общее состояние и демаскирование съезжало на резервный путь. Лимиты — # это потолок (docker compose без swarm не умеет в гарантированные reservations), # но они не дают соседям выесть Redis подчистую. services: prometheus: image: prom/prometheus:v2.54.1 command: - --config.file=/etc/prometheus/prometheus.yml - --storage.tsdb.retention.time=6h - --web.enable-lifecycle ports: - "9090:9090" volumes: - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus cpus: 0.5 mem_limit: 512m grafana: image: grafana/grafana:11.2.0 ports: - "3000:3000" environment: # Демонстрационный стенд: вход без пароля, чтобы жюри не искало учётные данные. # Для контура с реальными данными это надо снять. GF_AUTH_ANONYMOUS_ENABLED: "true" GF_AUTH_ANONYMOUS_ORG_ROLE: Admin GF_AUTH_DISABLE_LOGIN_FORM: "true" GF_USERS_DEFAULT_THEME: light # Сразу открывать дашборд модуля, а не пустую главную. GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH: /var/lib/grafana/dashboards/pd-guard.json volumes: - ./monitoring/grafana/provisioning:/etc/grafana/provisioning:ro - ./monitoring/grafana/dashboards:/var/lib/grafana/dashboards:ro - grafana-data:/var/lib/grafana cpus: 0.3 mem_limit: 512m redis: image: redis:7-alpine command: ["redis-server", "--save", "", "--appendonly", "no", "--maxmemory", "1gb", "--maxmemory-policy", "allkeys-lru"] healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 2s retries: 5 cpus: 1.0 mem_limit: 1200m node-a: &node image: pd-guard-spring:jvm cpus: 1.0 mem_limit: 2200m environment: PDGUARD_STORE_BACKEND: redis SPRING_DATA_REDIS_HOST: redis PDGUARD_MAX_CONCURRENT: "2000" PDGUARD_WARMUP_ITERATIONS: "2000" # Вторая ступень распознавания — две модели под разные задачи (см. # NameCascade.java): WikiNEuRal размечает имена, ruBERT — составляющие # адреса. Модели в репозиторий не входят: ./tools/fetch-ner-model.sh. # Пока движок не задан, соответствующая часть ступени выключена и # сервис работает на одних правилах. PDGUARD_NER_NAME_ENGINE: wikineural PDGUARD_NER_NAME_MODEL: /deployments/models/wikineural-ner PDGUARD_NER_ADDRESS_ENGINE: rubert PDGUARD_NER_ADDRESS_MODEL: /deployments/models/rubert-ner # ВРЕМЕННО для разового разбора формата тестовых payload'ов — пишет сырые ПД # в логи узла. LOGGING_LEVEL_* не подходит: relaxed binding из env приводит # имя логгера к нижнему регистру и не совпадает с ru.pdguard.core.Pipeline # (заглавная P), поэтому уровень задан через -D, где регистр сохраняется. # Выключить (убрать переменную) перед официальным нагрузочным прогоном. JAVA_OPTS: "-Dspring.config.additional-location=optional:file:/deployments/config/ -Dlogging.level.ru.pdguard.core.Pipeline=DEBUG" volumes: - ./config:/deployments/config:ro - ./models:/deployments/models:ro depends_on: redis: condition: service_healthy healthcheck: test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"] interval: 10s timeout: 2s retries: 3 node-b: <<: *node lb: image: nginx:1.27-alpine cpus: 0.3 mem_limit: 128m ports: - "8080:80" volumes: - ./nginx/lb.conf:/etc/nginx/nginx.conf:ro depends_on: node-a: condition: service_healthy node-b: condition: service_healthy volumes: prometheus-data: grafana-data: