Files
anti-plagiarism/docker-compose.prod.yml
jze9 e05e658d81
All checks were successful
Deploy / test (push) Successful in 3m48s
Deploy / deploy (push) Successful in 17m25s
feat(proxy): sing-box для обхода блокировки OpenRouter из РФ
OpenRouter отдаёт 403 с российских IP (подтверждено вживую). Добавлен
sing-box как отдельный сервис (VLESS+WS+TLS до ноды вне РФ) — только для
исходящих запросов к OpenRouter из ollama_client.py, остальной трафик
(Postgres/RabbitMQ/MinIO/Ollama) идёт напрямую. Реальный конфиг с UUID —
только на проде (см. config.json.example), в git не попадает.
2026-08-26 17:37:26 +05:00

193 lines
6.9 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ═══════════════════════════════════════════════════════════════════════════════
# ПРОД стек: локально — nginx (static+proxy), api, воркеры, elasticsearch.
# Удалённо (через .env) — postgres, redis, minio, ollama, rabbitmq.
# Тот же принцип, что и docker-compose.test.yml (не дублировать общую инфру),
# но без bind-mount'ов исходников, без --reload, с собранным фронтендом и nginx/TLS.
# Запуск: docker compose -f docker-compose.prod.yml up -d --build
# ═══════════════════════════════════════════════════════════════════════════════
networks:
antiplagiator:
driver: bridge
volumes:
es_prod_data:
faiss_index_prod:
qdrant_prod_data:
prometheus_data:
grafana_data:
x-app-env: &app-env
env_file: .env
networks:
- antiplagiator
restart: unless-stopped
services:
# ─── Локальная инфраструктура ──────────────────────────────────────────────
elasticsearch:
image: elasticsearch:8.13.0
container_name: antiplagiator-elasticsearch
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- xpack.ml.enabled=false
- ES_JAVA_OPTS=-Xms2g -Xmx2g
- bootstrap.memory_lock=true
- cluster.name=antiplagiator-prod
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- es_prod_data:/usr/share/elasticsearch/data
networks:
- antiplagiator
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health | grep -qv '\"status\":\"red\"'"]
interval: 15s
timeout: 10s
retries: 10
start_period: 60s
# Qdrant — альтернативный векторный бэкенд (снимает SPOF файлового FAISS).
# Опционален: поднимается только с профилем и активируется VECTOR_BACKEND=qdrant.
# docker compose -f docker-compose.prod.yml --profile qdrant up -d qdrant
# docker compose -f docker-compose.prod.yml exec worker-gpu python -m app.migrate_faiss_to_qdrant
# Тег сервера при необходимости поднять до версии клиента (qdrant-client 1.19).
qdrant:
image: qdrant/qdrant:v1.12.4
container_name: antiplagiator-qdrant
profiles: ["qdrant"]
volumes:
- qdrant_prod_data:/qdrant/storage
networks:
- antiplagiator
restart: unless-stopped
# ─── Наблюдаемость (опционально; профиль observability) ────────────────────
# docker compose -f docker-compose.prod.yml --profile observability up -d prometheus grafana
# Prometheus скрейпит api:/metrics и flower:/metrics (метрики Celery).
prometheus:
image: prom/prometheus:v2.54.1
container_name: antiplagiator-prometheus
profiles: ["observability"]
volumes:
- ./infra/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
networks:
- antiplagiator
restart: unless-stopped
grafana:
image: grafana/grafana:11.2.0
container_name: antiplagiator-grafana
profiles: ["observability"]
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin}
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- ./infra/grafana/provisioning:/etc/grafana/provisioning:ro
- grafana_data:/var/lib/grafana
networks:
- antiplagiator
restart: unless-stopped
depends_on:
- prometheus
# ─── Приложение ────────────────────────────────────────────────────────────
# RabbitMQ вынесен на отдельный сервер 192.168.20.82 (см. RABBITMQ_URL в .env)
api:
build:
context: ./services/api
dockerfile: Dockerfile
container_name: antiplagiator-api
<<: *app-env
depends_on:
elasticsearch:
condition: service_healthy
# SOCKS5-прокси (sing-box → VLESS-нода вне РФ) — OpenRouter недоступен
# напрямую из России, только для этого и нужен. Остальной трафик
# worker-gpu (Postgres/RabbitMQ/MinIO/Ollama) идёт напрямую, не через него.
singbox-proxy:
image: ghcr.io/sagernet/sing-box:v1.10.0
container_name: antiplagiator-singbox-proxy
command: run -c /etc/sing-box/config.json
volumes:
- ./infra/singbox/config.json:/etc/sing-box/config.json:ro
networks:
- antiplagiator
restart: unless-stopped
worker-gpu:
build:
context: ./services/worker-gpu
dockerfile: Dockerfile
container_name: antiplagiator-worker-gpu
<<: *app-env
volumes:
- faiss_index_prod:/data/index
depends_on:
elasticsearch:
condition: service_healthy
singbox-proxy:
condition: service_started
worker-indexer:
build:
context: ./services/worker-indexer
dockerfile: Dockerfile
container_name: antiplagiator-worker-indexer
<<: *app-env
volumes:
- ./scripts/parsers:/parsers:ro
depends_on:
elasticsearch:
condition: service_healthy
worker-notifier:
build:
context: ./services/worker-notifier
dockerfile: Dockerfile
container_name: antiplagiator-worker-notifier
<<: *app-env
worker-gost:
build:
context: ./services/worker-gost
dockerfile: Dockerfile
container_name: antiplagiator-worker-gost
<<: *app-env
flower:
image: mher/flower:2.0
container_name: antiplagiator-flower
command: celery --broker=${RABBITMQ_URL} flower --port=5555
environment:
CELERY_BROKER_URL: ${RABBITMQ_URL}
CELERY_RESULT_BACKEND: ${REDIS_URL}
networks:
- antiplagiator
restart: unless-stopped
# Flower не публикуется наружу напрямую — доступ через ssh-туннель при необходимости
# ─── Nginx: собранный фронтенд (static) + proxy /api, /ws → api:8000, TLS ──
nginx:
build:
context: .
dockerfile: infra/nginx/Dockerfile
container_name: antiplagiator-nginx
networks:
- antiplagiator
ports:
- "80:80"
- "443:443"
volumes:
- /etc/letsencrypt:/etc/letsencrypt:ro
depends_on:
- api
restart: unless-stopped