P3.2 — Multi-node deployment: - Added node-worker service to docker-compose.node1.yml (NODE_ID=noda1) - NCS NODA1 now has NODE_WORKER_URL for metrics collection - Fixed NODE_ID consistency: router NODA1 uses 'noda1' - NODA2 node-worker/NCS gets NCS_REPORT_URL for latency reporting P3.3 — NATS accounts/auth (opt-in config): - config/nats-server.conf with 3 accounts: SYS, FABRIC, APP - Per-user topic permissions (router, ncs, node_worker) - Leafnode listener :7422 with auth - Not yet activated (requires credential provisioning) P3.4 — Prometheus counters: - Router /fabric_metrics: caps_refresh, caps_stale, model_select, offload_total, breaker_state, score_ms histogram - Node Worker /prom_metrics: jobs_total, inflight gauge, latency_ms histogram - NCS /prom_metrics: runtime_health, runtime_p50/p95, node_wait_ms - All bound to 127.0.0.1 (not externally exposed) Made-with: Cursor
1152 lines
37 KiB
YAML
1152 lines
37 KiB
YAML
version: '3.8'
|
||
|
||
services:
|
||
# DAGI Router для NODE1
|
||
router:
|
||
build:
|
||
context: ./services/router
|
||
dockerfile: Dockerfile
|
||
container_name: dagi-router-node1
|
||
ports:
|
||
- "9102:8000"
|
||
environment:
|
||
- NATS_URL=nats://nats:4222
|
||
- ROUTER_CONFIG_PATH=/app/router_config.yaml
|
||
- LOG_LEVEL=info
|
||
- NODE_ID=noda1
|
||
- MEMORY_SERVICE_URL=http://memory-service:8000
|
||
# Timeout policy: Gateway (180s) > Router (60s) > LLM (30s)
|
||
- ROUTER_TIMEOUT=180
|
||
- QDRANT_HOST=qdrant
|
||
- QDRANT_PORT=6333
|
||
- QDRANT_ENABLED=true
|
||
- NEO4J_BOLT_URL=bolt://neo4j:7687
|
||
- NEO4J_HTTP_URL=http://neo4j:7474
|
||
- NEO4J_USER=neo4j
|
||
- NEO4J_PASSWORD=DaarionNeo4j2026!
|
||
- DEEPSEEK_API_KEY=sk-0db94e8193ec4a6e9acd593ee8d898e7
|
||
- MISTRAL_API_KEY=40Gwjo8nVBx4i4vIkgszvXw9bOwDOu4G
|
||
- COHERE_API_KEY=nOdOXnuepLku2ipJWpe6acWgAsJCsDhMO0RnaEJB
|
||
- GROK_API_KEY=xai-CpoLMPgw91NP9AEdHPhIrvU4ZnhV1q1P8BJBKCpD5kTPFRXJmTOkgGNHwYdZpXMlRxBgHcgcSlIXccxh
|
||
- VISION_ENCODER_URL=http://vision-encoder:8001
|
||
- SWAPPER_SERVICE_URL=http://swapper-service:8890
|
||
- IMAGE_GEN_URL=http://swapper-service:8890/image/generate
|
||
- STT_SERVICE_URL=http://swapper-service:8890
|
||
- STT_SERVICE_UPLOAD_URL=http://swapper-service:8890/stt
|
||
- OCR_SERVICE_URL=http://swapper-service:8890
|
||
- WEB_SEARCH_SERVICE_URL=http://swapper-service:8890
|
||
- REDIS_URL=redis://redis:6379/0
|
||
- CREWAI_SERVICE_URL=http://dagi-staging-crewai-service:9010
|
||
- NATURE_ID_URL=http://plant-vision-node1:8085
|
||
- NATURE_ID_MIN_CONFIDENCE=0.65
|
||
- PLANTNET_API_KEY=${PLANTNET_API_KEY}
|
||
- ONEOK_CRM_BASE_URL=http://oneok-crm-adapter:8088
|
||
- ONEOK_CALC_BASE_URL=http://oneok-calc-adapter:8089
|
||
- ONEOK_DOCS_BASE_URL=http://oneok-docs-adapter:8090
|
||
- ONEOK_SCHEDULE_BASE_URL=http://oneok-schedule-adapter:8091
|
||
- ONEOK_ADAPTER_API_KEY=${ONEOK_ADAPTER_API_KEY}
|
||
- ROUTER_TOOL_MAX_ROUNDS=${ROUTER_TOOL_MAX_ROUNDS:-10}
|
||
- AGROMATRIX_REVIEW_AUTH_MODE=${AGROMATRIX_REVIEW_AUTH_MODE:-bearer}
|
||
- AGROMATRIX_REVIEW_BEARER_TOKENS=${AGROMATRIX_REVIEW_BEARER_TOKENS}
|
||
# ── Node Capabilities (multi-node model selection) ──
|
||
- NODE_CAPABILITIES_URL=http://node-capabilities:8099/capabilities
|
||
- ENABLE_GLOBAL_CAPS_NATS=true
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/services/router/router_config.yaml:/app/router_config.yaml:ro
|
||
- ${DEPLOY_ROOT:-.}/services/router/router-config.yml:/app/router-config.yml:ro
|
||
- ${DEPLOY_ROOT:-.}/config/crewai_agents.json:/config/crewai_agents.json:ro
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/health')\""]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 10s
|
||
|
||
# Swapper Service для NODE1 - Dynamic LLM + OCR model loading
|
||
swapper-service:
|
||
build:
|
||
context: ./services/swapper-service
|
||
dockerfile: Dockerfile
|
||
container_name: swapper-service-node1
|
||
ports:
|
||
- "8890:8890"
|
||
- "8891:8891" # Metrics
|
||
environment:
|
||
- OLLAMA_BASE_URL=http://172.18.0.1:11434
|
||
- SWAPPER_CONFIG_PATH=/app/config/swapper_config.yaml
|
||
- SWAPPER_MODE=single-active
|
||
- MAX_CONCURRENT_MODELS=2 # 1 LLM + 1 OCR
|
||
- MODEL_SWAP_TIMEOUT=300
|
||
- GPU_ENABLED=true
|
||
- NODE_ID=node-1-hetzner-gex44
|
||
- HF_HOME=/root/.cache/huggingface
|
||
- CUDA_VISIBLE_DEVICES=0
|
||
- CRAWL4AI_URL=http://crawl4ai:11235
|
||
# Cloud API keys for video/image generation
|
||
- GROK_API_KEY=xai-CpoLMPgw91NP9AEdHPhIrvU4ZnhV1q1P8BJBKCpD5kTPFRXJmTOkgGNHwYdZpXMlRxBgHcgcSlIXccxh
|
||
- MISTRAL_API_KEY=40Gwjo8nVBx4i4vIkgszvXw9bOwDOu4G
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/services/swapper-service/config/swapper_config_node1.yaml:/app/config/swapper_config.yaml:ro
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
- swapper-hf-cache-node1:/root/.cache/huggingface
|
||
# GPU support for OCR models
|
||
deploy:
|
||
resources:
|
||
reservations:
|
||
devices:
|
||
- driver: nvidia
|
||
count: 1
|
||
capabilities: [gpu]
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
extra_hosts:
|
||
- "host.docker.internal:172.18.0.1"
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "wget -qO- http://localhost:8890/health || exit 1"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 60s
|
||
|
||
# Image Generation тепер інтегровано в Swapper Service (lazy loading)
|
||
# Endpoint: POST /image/generate на swapper-service:8890
|
||
|
||
# Plant Vision wrapper (local nature-id CLI -> HTTP)
|
||
plant-vision-node1:
|
||
build:
|
||
context: ./services/plant-vision-node1
|
||
dockerfile: Dockerfile
|
||
container_name: plant-vision-node1
|
||
environment:
|
||
- NATURE_ID_CMD=${NATURE_ID_CMD:-python /opt/nature-id/nature_id.py -m plants -l -r 5 -s {image_path}}
|
||
- NATURE_ID_TIMEOUT=40
|
||
- DOWNLOAD_TIMEOUT=20
|
||
networks:
|
||
- dagi-network
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/third_party/nature-id:/opt/nature-id:ro
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8085/health')\""]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 15s
|
||
|
||
# Crawl4AI - Advanced Web Crawler with JavaScript support
|
||
crawl4ai:
|
||
image: unclecode/crawl4ai@sha256:4d8b065bf185962733cb5f9701f4122d03383fa1ab6b5f6a9873f04fa0416a84
|
||
container_name: dagi-crawl4ai-node1
|
||
ports:
|
||
- "11235:11235"
|
||
environment:
|
||
- CRAWL4AI_API_TOKEN=${CRAWL4AI_API_TOKEN:-}
|
||
- MAX_CONCURRENT_TASKS=5
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:11235/health"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 30s
|
||
|
||
# Gateway Bot (Helion + DAARWIZZ)
|
||
gateway:
|
||
build:
|
||
context: ./gateway-bot
|
||
dockerfile: Dockerfile
|
||
container_name: dagi-gateway-node1
|
||
ports:
|
||
- "9300:9300"
|
||
environment:
|
||
- ROUTER_URL=${ROUTER_URL:-http://dagi-staging-router:8000}
|
||
- GATEWAY_MAX_TOKENS_CONCISE=350
|
||
- GATEWAY_MAX_TOKENS_SENPAI_DEFAULT=700
|
||
- GATEWAY_MAX_TOKENS_DEFAULT=700
|
||
- GATEWAY_MAX_TOKENS_DETAILED=1200
|
||
- SERVICE_ID=gateway
|
||
- SERVICE_ROLE=gateway
|
||
- BRAND_INTAKE_URL=http://brand-intake:9211
|
||
- BRAND_REGISTRY_URL=http://brand-registry:9210
|
||
- PRESENTATION_RENDERER_URL=http://presentation-renderer:9212
|
||
- ARTIFACT_REGISTRY_URL=http://artifact-registry:9220
|
||
- HELION_TELEGRAM_BOT_TOKEN=8112062582:AAGS-HwRLEI269lDutLtAJTFArsIq31YNhE
|
||
- HELION_NAME=Helion
|
||
- HELION_PROMPT_PATH=/app/gateway-bot/helion_prompt.txt
|
||
- NUTRA_TELEGRAM_BOT_TOKEN=8517315428:AAGTLcKxBAZDsMgx28agKTvl1SqJGi0utH4
|
||
- NUTRA_NAME=NUTRA
|
||
- DRUID_TELEGRAM_BOT_TOKEN=8145618489:AAFR714mBsNmiuF-rjCw-295iORBReJQZ70
|
||
- DRUID_NAME=Druid
|
||
- DRUID_PROMPT_PATH=/app/gateway-bot/druid_prompt.txt
|
||
- DAARWIZZ_TELEGRAM_BOT_TOKEN=8323412397:AAGZbAR22LuOiGD8xVC3OXMjahQ8rs2lJwo
|
||
- DAARWIZZ_NAME=DAARWIZZ
|
||
- DAARWIZZ_PROMPT_PATH=/app/gateway-bot/daarwizz_prompt.txt
|
||
- GREENFOOD_TELEGRAM_BOT_TOKEN=7495165343:AAGR1XEOzg7DkPFPCzL_eYLCJfxJuonCxug
|
||
- GREENFOOD_NAME=GREENFOOD
|
||
- GREENFOOD_PROMPT_PATH=/app/gateway-bot/greenfood_prompt.txt
|
||
- AGROMATRIX_TELEGRAM_BOT_TOKEN=8580290441:AAFuDBmFJtpl-3I_WfkH7Hkb59X0fhYNMOE
|
||
- AGROMATRIX_NAME=AgroMatrix
|
||
- AGROMATRIX_PROMPT_PATH=/app/gateway-bot/agromatrix_prompt.txt
|
||
# Alateya - R&D, біотех, інновації
|
||
- ALATEYA_TELEGRAM_BOT_TOKEN=8436880945:AAEi-HS6GEctddoqBUd37MHfweZQP-OjRlo
|
||
- ALATEYA_NAME=Alateya
|
||
- ALATEYA_PROMPT_PATH=/app/gateway-bot/alateya_prompt.txt
|
||
# Clan (Spirit) - Дух Общини
|
||
- CLAN_TELEGRAM_BOT_TOKEN=8516872152:AAHH26wU8hJZJbSCJXb4vbmPmakTP77ok5E
|
||
- CLAN_NAME=Spirit
|
||
- CLAN_PROMPT_PATH=/app/gateway-bot/clan_prompt.txt
|
||
# Eonarch - Еволюція свідомості
|
||
- EONARCH_TELEGRAM_BOT_TOKEN=7962391584:AAFYkelLRG3VR_Lxuu6pEGG76t4vZdANtz4
|
||
- EONARCH_NAME=EONARCH
|
||
- EONARCH_PROMPT_PATH=/app/gateway-bot/eonarch_prompt.txt
|
||
- SENPAI_TELEGRAM_BOT_TOKEN=8510265026:AAGFrFBIIEihsLptZSxuKdmW2RoRPQDY9FE
|
||
- ONEOK_TELEGRAM_BOT_TOKEN=${ONEOK_TELEGRAM_BOT_TOKEN}
|
||
- SOUL_TELEGRAM_BOT_TOKEN=8041596416:AAHhpfCtY8paCm_9AD-4stJJg-Vw-CBf6Qk
|
||
- YAROMIR_TELEGRAM_BOT_TOKEN=8128180674:AAGNZdG3LwECI4z_803smsuRHsK3nPdjMLY
|
||
- SOFIIA_TELEGRAM_BOT_TOKEN=8589292566:AAEmPvS6nY9e-Y-TZm04CAHWlaFnWVxajE4
|
||
- SENPAI_NAME=SENPAI
|
||
- ONEOK_NAME=1OK
|
||
- SOUL_NAME=Athena
|
||
- YAROMIR_NAME=Yaromir
|
||
- SOFIIA_NAME=Sophia
|
||
- SENPAI_PROMPT_PATH=/app/gateway-bot/senpai_prompt.txt
|
||
- ONEOK_PROMPT_PATH=/app/gateway-bot/oneok_prompt.txt
|
||
- MEMORY_SERVICE_URL=http://memory-service:8000
|
||
# Timeout policy: Gateway (180s) > Router (60s) > LLM (30s)
|
||
- ROUTER_TIMEOUT=180
|
||
- SWAPPER_SERVICE_URL=http://swapper-service:8890
|
||
- IMAGE_GEN_URL=http://swapper-service:8890/image/generate
|
||
- STT_SERVICE_URL=http://swapper-service:8890
|
||
- STT_SERVICE_UPLOAD_URL=http://swapper-service:8890/stt
|
||
- OCR_SERVICE_URL=http://swapper-service:8890
|
||
- WEB_SEARCH_SERVICE_URL=http://swapper-service:8890
|
||
- REDIS_URL=redis://redis:6379/0
|
||
- CREWAI_SERVICE_URL=http://dagi-staging-crewai-service:9010
|
||
- AGROMATRIX_REVIEW_AUTH_MODE=${AGROMATRIX_REVIEW_AUTH_MODE:-bearer}
|
||
- AGROMATRIX_REVIEW_BEARER_TOKENS=${AGROMATRIX_REVIEW_BEARER_TOKENS}
|
||
# v4.3 FarmOS integration (fail-closed: якщо пусто — агент повідомить "не налаштований")
|
||
- FARMOS_BASE_URL=http://dagi-farmos-node1
|
||
- FARMOS_TOKEN=${FARMOS_TOKEN:-}
|
||
- FARMOS_USER=${FARMOS_USER:-}
|
||
- FARMOS_PASS=${FARMOS_PASS:-}
|
||
- FARMOS_CLIENT_ID=${FARMOS_CLIENT_ID:-farm}
|
||
env_file:
|
||
- .env.stepan.node1
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/gateway-bot:/app/gateway-bot:ro
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
depends_on:
|
||
- router
|
||
- memory-service
|
||
- redis
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:9300/health')\""]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 10s
|
||
|
||
|
||
gateway-worker:
|
||
build:
|
||
context: ./gateway-bot
|
||
dockerfile: Dockerfile
|
||
container_name: dagi-gateway-worker-node1
|
||
command: ["python", "-m", "daarion_facade.worker"]
|
||
environment:
|
||
- ROUTER_BASE_URL=http://router:8000
|
||
- REDIS_URL=redis://redis:6379/0
|
||
- ROUTER_WORKER_TIMEOUT=60
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/gateway-bot:/app/gateway-bot:ro
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
depends_on:
|
||
- router
|
||
- redis
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD", "python", "-c", "print(\"ok\")"]
|
||
interval: 30s
|
||
timeout: 5s
|
||
retries: 3
|
||
|
||
|
||
gateway-reminder-worker:
|
||
build:
|
||
context: ./gateway-bot
|
||
dockerfile: Dockerfile
|
||
container_name: dagi-gateway-reminder-worker-node1
|
||
command: ["python", "-m", "daarion_facade.reminder_worker"]
|
||
environment:
|
||
- REDIS_URL=redis://redis:6379/0
|
||
- DAARION_REMINDER_POLL_SECONDS=${DAARION_REMINDER_POLL_SECONDS:-2}
|
||
- DAARION_REMINDER_TTL_SECONDS=${DAARION_REMINDER_TTL_SECONDS:-2592000}
|
||
- DAARION_REMINDER_DEFAULT_TZ=${DAARION_REMINDER_DEFAULT_TZ:-Europe/Kyiv}
|
||
- GLOBAL_RELAY_ALLOWED_USER_IDS=${GLOBAL_RELAY_ALLOWED_USER_IDS:-}
|
||
- MENTOR_PRIVATE_HANDLES=${MENTOR_PRIVATE_HANDLES:-ivantytar,archenvis,olegarch88}
|
||
- MENTOR_PRIVATE_NAMES=${MENTOR_PRIVATE_NAMES:-Іван Титар,Александр Вертій,Олег Ковальчук}
|
||
- MENTOR_DISCLOSURE_ALLOWED_USER_IDS=${MENTOR_DISCLOSURE_ALLOWED_USER_IDS:-}
|
||
- HELION_MENTOR_CHAT_IDS=${HELION_MENTOR_CHAT_IDS:-}
|
||
- HELION_RELAY_ALLOWED_USER_IDS=${HELION_RELAY_ALLOWED_USER_IDS:-}
|
||
- DAARWIZZ_TELEGRAM_BOT_TOKEN=${DAARWIZZ_TELEGRAM_BOT_TOKEN:-8323412397:AAGZbAR22LuOiGD8xVC3OXMjahQ8rs2lJwo}
|
||
- HELION_TELEGRAM_BOT_TOKEN=${HELION_TELEGRAM_BOT_TOKEN:-8112062582:AAGS-HwRLEI269lDutLtAJTFArsIq31YNhE}
|
||
- GREENFOOD_TELEGRAM_BOT_TOKEN=${GREENFOOD_TELEGRAM_BOT_TOKEN:-7495165343:AAGR1XEOzg7DkPFPCzL_eYLCJfxJuonCxug}
|
||
- AGROMATRIX_TELEGRAM_BOT_TOKEN=${AGROMATRIX_TELEGRAM_BOT_TOKEN:-8580290441:AAFuDBmFJtpl-3I_WfkH7Hkb59X0fhYNMOE}
|
||
- ALATEYA_TELEGRAM_BOT_TOKEN=${ALATEYA_TELEGRAM_BOT_TOKEN:-8436880945:AAEi-HS6GEctddoqBUd37MHfweZQP-OjRlo}
|
||
- NUTRA_TELEGRAM_BOT_TOKEN=${NUTRA_TELEGRAM_BOT_TOKEN:-8517315428:AAGTLcKxBAZDsMgx28agKTvl1SqJGi0utH4}
|
||
- DRUID_TELEGRAM_BOT_TOKEN=${DRUID_TELEGRAM_BOT_TOKEN:-8145618489:AAFR714mBsNmiuF-rjCw-295iORBReJQZ70}
|
||
- CLAN_TELEGRAM_BOT_TOKEN=${CLAN_TELEGRAM_BOT_TOKEN:-8516872152:AAHH26wU8hJZJbSCJXb4vbmPmakTP77ok5E}
|
||
- EONARCH_TELEGRAM_BOT_TOKEN=${EONARCH_TELEGRAM_BOT_TOKEN:-7962391584:AAFYkelLRG3VR_Lxuu6pEGG76t4vZdANtz4}
|
||
- SENPAI_TELEGRAM_BOT_TOKEN=${SENPAI_TELEGRAM_BOT_TOKEN:-8510265026:AAGFrFBIIEihsLptZSxuKdmW2RoRPQDY9FE}
|
||
- ONEOK_TELEGRAM_BOT_TOKEN=${ONEOK_TELEGRAM_BOT_TOKEN}
|
||
- SOUL_TELEGRAM_BOT_TOKEN=${SOUL_TELEGRAM_BOT_TOKEN:-8041596416:AAHhpfCtY8paCm_9AD-4stJJg-Vw-CBf6Qk}
|
||
- YAROMIR_TELEGRAM_BOT_TOKEN=${YAROMIR_TELEGRAM_BOT_TOKEN:-8128180674:AAGNZdG3LwECI4z_803smsuRHsK3nPdjMLY}
|
||
- SOFIIA_TELEGRAM_BOT_TOKEN=${SOFIIA_TELEGRAM_BOT_TOKEN:-8589292566:AAEmPvS6nY9e-Y-TZm04CAHWlaFnWVxajE4}
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/gateway-bot:/app/gateway-bot:ro
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
depends_on:
|
||
- redis
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD", "python", "-c", "print(\"ok\")"]
|
||
interval: 30s
|
||
timeout: 5s
|
||
retries: 3
|
||
|
||
|
||
metrics-poller-node1:
|
||
build:
|
||
context: ./gateway-bot
|
||
dockerfile: Dockerfile
|
||
container_name: dagi-metrics-poller-node1
|
||
command: ["python", "-m", "daarion_facade.metrics_poller"]
|
||
environment:
|
||
- REDIS_URL=redis://redis:6379/0
|
||
- MEMORY_SERVICE_URL=http://memory-service:8000
|
||
- DAARION_METRICS_POLL_INTERVAL_SECONDS=${DAARION_METRICS_POLL_INTERVAL_SECONDS:-10}
|
||
- DAARION_METRICS_TTL_SECONDS=${DAARION_METRICS_TTL_SECONDS:-60}
|
||
- DAARION_METRICS_HTTP_CONNECT_TIMEOUT_SECONDS=${DAARION_METRICS_HTTP_CONNECT_TIMEOUT_SECONDS:-2}
|
||
- DAARION_METRICS_HTTP_TOTAL_TIMEOUT_SECONDS=${DAARION_METRICS_HTTP_TOTAL_TIMEOUT_SECONDS:-5}
|
||
- DAARION_NODE_COUNT=${DAARION_NODE_COUNT:-1}
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/gateway-bot:/app/gateway-bot:ro
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
depends_on:
|
||
- redis
|
||
- memory-service
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD", "python", "-c", "print(\"ok\")"]
|
||
interval: 30s
|
||
timeout: 5s
|
||
retries: 3
|
||
# CLAN Consent Outbox Worker (Postgres event-store applier; no execute)
|
||
clan-consent-outbox-worker:
|
||
build:
|
||
context: ./services/clan-consent-adapter
|
||
dockerfile: Dockerfile
|
||
container_name: clan-consent-outbox-worker
|
||
command: ["python", "clan_consent_outbox_worker.py"]
|
||
environment:
|
||
- CLAN_PG_DSN=${CLAN_PG_DSN:-postgresql://daarion:DaarionDB2026!@dagi-postgres:5432/daarion_main}
|
||
- CLAN_OUTBOX_BATCH_SIZE=${CLAN_OUTBOX_BATCH_SIZE:-10}
|
||
- CLAN_OUTBOX_POLL_INTERVAL_SEC=${CLAN_OUTBOX_POLL_INTERVAL_SEC:-1.0}
|
||
- CLAN_OUTBOX_MAX_CAS_RETRIES=${CLAN_OUTBOX_MAX_CAS_RETRIES:-5}
|
||
- CLAN_CONSENT_APPLIER_ACTOR_ID=${CLAN_CONSENT_APPLIER_ACTOR_ID:-system:consent-applier}
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
depends_on:
|
||
- dagi-postgres
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# 1OK - EspoCRM DB
|
||
oneok-espocrm-db:
|
||
image: mariadb:11
|
||
container_name: oneok-espocrm-db-node1
|
||
environment:
|
||
- MARIADB_ROOT_PASSWORD=${ONEOK_ESPO_DB_ROOT_PASSWORD:-change_me_root}
|
||
- MARIADB_DATABASE=${ONEOK_ESPO_DB_NAME:-oneok_espocrm}
|
||
- MARIADB_USER=${ONEOK_ESPO_DB_USER:-oneok}
|
||
- MARIADB_PASSWORD=${ONEOK_ESPO_DB_PASSWORD:-change_me_oneok}
|
||
volumes:
|
||
- oneok-espocrm-db-node1:/var/lib/mysql
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# 1OK - EspoCRM
|
||
oneok-espocrm:
|
||
image: espocrm/espocrm:latest
|
||
container_name: oneok-espocrm-node1
|
||
ports:
|
||
- "9080:80"
|
||
environment:
|
||
- ESPOCRM_DATABASE_HOST=oneok-espocrm-db
|
||
- ESPOCRM_DATABASE_NAME=${ONEOK_ESPO_DB_NAME:-oneok_espocrm}
|
||
- ESPOCRM_DATABASE_USER=${ONEOK_ESPO_DB_USER:-oneok}
|
||
- ESPOCRM_DATABASE_PASSWORD=${ONEOK_ESPO_DB_PASSWORD:-change_me_oneok}
|
||
- ESPOCRM_ADMIN_USERNAME=${ONEOK_ESPO_ADMIN_USER:-admin}
|
||
- ESPOCRM_ADMIN_PASSWORD=${ONEOK_ESPO_ADMIN_PASSWORD:-change_me_admin}
|
||
- ESPOCRM_SITE_URL=${ONEOK_ESPO_SITE_URL:-http://localhost:9080}
|
||
depends_on:
|
||
- oneok-espocrm-db
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# 1OK - Gotenberg PDF
|
||
oneok-gotenberg:
|
||
image: gotenberg/gotenberg:8
|
||
container_name: oneok-gotenberg-node1
|
||
command:
|
||
- gotenberg
|
||
- --api-timeout=30s
|
||
- --api-port=3000
|
||
- --chromium-disable-routes=true
|
||
ports:
|
||
- "3010:3000"
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# 1OK - CRM Adapter
|
||
oneok-crm-adapter:
|
||
build:
|
||
context: ./services/oneok-crm-adapter
|
||
dockerfile: Dockerfile
|
||
container_name: oneok-crm-adapter-node1
|
||
environment:
|
||
- ONEOK_ADAPTER_API_KEY=${ONEOK_ADAPTER_API_KEY}
|
||
- ONEOK_CRM_DB_PATH=/data/oneok_crm.sqlite
|
||
- ONEOK_ESPO_URL=http://oneok-espocrm
|
||
- ONEOK_ESPO_API_KEY=${ONEOK_ESPO_API_KEY}
|
||
volumes:
|
||
- oneok-crm-data-node1:/data
|
||
depends_on:
|
||
- oneok-espocrm
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# 1OK - Docs Adapter
|
||
oneok-docs-adapter:
|
||
build:
|
||
context: ./services/oneok-docs-adapter
|
||
dockerfile: Dockerfile
|
||
container_name: oneok-docs-adapter-node1
|
||
environment:
|
||
- ONEOK_ADAPTER_API_KEY=${ONEOK_ADAPTER_API_KEY}
|
||
- ONEOK_GOTENBERG_URL=http://oneok-gotenberg:3000
|
||
depends_on:
|
||
- oneok-gotenberg
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# 1OK - Calc Adapter
|
||
oneok-calc-adapter:
|
||
build:
|
||
context: ./services/oneok-calc-adapter
|
||
dockerfile: Dockerfile
|
||
container_name: oneok-calc-adapter-node1
|
||
environment:
|
||
- ONEOK_ADAPTER_API_KEY=${ONEOK_ADAPTER_API_KEY}
|
||
- ONEOK_BASE_RATE_PER_M2=${ONEOK_BASE_RATE_PER_M2:-3200}
|
||
- ONEOK_INSTALL_RATE_PER_M2=${ONEOK_INSTALL_RATE_PER_M2:-900}
|
||
- ONEOK_CURRENCY=${ONEOK_CURRENCY:-UAH}
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# 1OK - Schedule Adapter
|
||
oneok-schedule-adapter:
|
||
build:
|
||
context: ./services/oneok-schedule-adapter
|
||
dockerfile: Dockerfile
|
||
container_name: oneok-schedule-adapter-node1
|
||
environment:
|
||
- ONEOK_ADAPTER_API_KEY=${ONEOK_ADAPTER_API_KEY}
|
||
- ONEOK_SCHEDULE_TZ=Europe/Kyiv
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# Node Capabilities Service (model inventory for router)
|
||
node-capabilities:
|
||
build:
|
||
context: ./services/node-capabilities
|
||
dockerfile: Dockerfile
|
||
container_name: node-capabilities-node1
|
||
environment:
|
||
- NODE_ID=noda1
|
||
- OLLAMA_BASE_URL=http://host.docker.internal:11434
|
||
- SWAPPER_URL=http://swapper-service:8890
|
||
- CACHE_TTL_SEC=15
|
||
- ENABLE_NATS_CAPS=true
|
||
- NATS_URL=nats://nats:4222
|
||
- NODE_WORKER_URL=http://node-worker:8109
|
||
extra_hosts:
|
||
- "host.docker.internal:host-gateway"
|
||
depends_on:
|
||
- nats
|
||
networks:
|
||
dagi-network:
|
||
aliases:
|
||
- node-capabilities
|
||
restart: unless-stopped
|
||
|
||
# Node Worker — NATS offload executor
|
||
node-worker:
|
||
build:
|
||
context: ./services/node-worker
|
||
dockerfile: Dockerfile
|
||
container_name: node-worker-node1
|
||
ports:
|
||
- "127.0.0.1:8109:8109"
|
||
extra_hosts:
|
||
- "host.docker.internal:host-gateway"
|
||
environment:
|
||
- NODE_ID=noda1
|
||
- NATS_URL=nats://nats:4222
|
||
- OLLAMA_BASE_URL=http://host.docker.internal:11434
|
||
- SWAPPER_URL=http://swapper-service:8890
|
||
- NODE_DEFAULT_LLM=qwen3.5:27b
|
||
- NODE_DEFAULT_VISION=qwen3-vl-8b
|
||
- NODE_WORKER_MAX_CONCURRENCY=2
|
||
- NCS_REPORT_URL=http://node-capabilities:8099
|
||
depends_on:
|
||
- nats
|
||
- swapper-service
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# NATS (JetStream)
|
||
nats:
|
||
image: nats:2.10-alpine
|
||
container_name: dagi-nats-node1
|
||
ports:
|
||
- "4222:4222"
|
||
command: ["-js"]
|
||
volumes:
|
||
- nats-data-node1:/data
|
||
networks:
|
||
dagi-network:
|
||
aliases:
|
||
- nats
|
||
restart: unless-stopped
|
||
|
||
# MinIO Object Storage
|
||
minio:
|
||
image: minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
|
||
container_name: dagi-minio-node1
|
||
ports:
|
||
- "9000:9000"
|
||
- "9001:9001"
|
||
environment:
|
||
- MINIO_ROOT_USER=minioadmin
|
||
- MINIO_ROOT_PASSWORD=minioadmin
|
||
command: ["server", "/data", "--console-address", ":9001"]
|
||
volumes:
|
||
- minio-data-node1:/data
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# Artifact Registry (shared for docs/presentations)
|
||
artifact-registry:
|
||
build:
|
||
context: ./services/artifact-registry
|
||
dockerfile: Dockerfile
|
||
container_name: artifact-registry-node1
|
||
ports:
|
||
- "9220:9220"
|
||
environment:
|
||
- POSTGRES_HOST=dagi-postgres
|
||
- POSTGRES_PORT=5432
|
||
- POSTGRES_USER=daarion
|
||
- POSTGRES_PASSWORD=DaarionDB2026!
|
||
- POSTGRES_DB=daarion_main
|
||
- MINIO_ENDPOINT=minio:9000
|
||
- MINIO_ACCESS_KEY=minioadmin
|
||
- MINIO_SECRET_KEY=minioadmin
|
||
- MINIO_BUCKET=artifacts
|
||
- MINIO_SECURE=false
|
||
- NATS_URL=nats://nats:4222
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
depends_on:
|
||
- nats
|
||
- minio
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:9220/health')\""]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 10s
|
||
|
||
# RAG Service (pgvector)
|
||
rag-service:
|
||
build:
|
||
context: ./services/rag-service
|
||
dockerfile: Dockerfile
|
||
container_name: rag-service-node1
|
||
ports:
|
||
- "9500:9500"
|
||
environment:
|
||
- PG_DSN=postgresql+psycopg2://daarion:DaarionDB2026!@dagi-postgres:5432/rag
|
||
- RAG_TABLE_NAME=rag_documents
|
||
depends_on:
|
||
- dagi-postgres
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD", "wget", "-qO-", "http://localhost:9500/health"]
|
||
interval: 10s
|
||
timeout: 3s
|
||
retries: 10
|
||
|
||
# PPTX Render Worker
|
||
render-pptx-worker:
|
||
build:
|
||
context: ./services/render-pptx-worker
|
||
dockerfile: Dockerfile
|
||
container_name: render-pptx-worker-node1
|
||
environment:
|
||
- NATS_URL=nats://nats:4222
|
||
- ARTIFACT_REGISTRY_URL=http://artifact-registry:9220
|
||
- MINIO_ENDPOINT=minio:9000
|
||
- MINIO_ACCESS_KEY=minioadmin
|
||
- MINIO_SECRET_KEY=minioadmin
|
||
- MINIO_BUCKET=artifacts
|
||
- MINIO_SECURE=false
|
||
depends_on:
|
||
- nats
|
||
- artifact-registry
|
||
- minio
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# PDF Render Worker (LibreOffice)
|
||
render-pdf-worker:
|
||
build:
|
||
context: ./services/render-pdf-worker
|
||
dockerfile: Dockerfile
|
||
container_name: render-pdf-worker-node1
|
||
environment:
|
||
- NATS_URL=nats://nats:4222
|
||
- ARTIFACT_REGISTRY_URL=http://artifact-registry:9220
|
||
- MINIO_ENDPOINT=minio:9000
|
||
- MINIO_ACCESS_KEY=minioadmin
|
||
- MINIO_SECRET_KEY=minioadmin
|
||
- MINIO_BUCKET=artifacts
|
||
- MINIO_SECURE=false
|
||
depends_on:
|
||
- nats
|
||
- artifact-registry
|
||
- minio
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
stop_grace_period: 30s
|
||
|
||
# Index Doc Worker
|
||
index-doc-worker:
|
||
build:
|
||
context: ./services/index-doc-worker
|
||
dockerfile: Dockerfile
|
||
container_name: index-doc-worker-node1
|
||
environment:
|
||
- NATS_URL=nats://nats:4222
|
||
- ARTIFACT_REGISTRY_URL=http://artifact-registry:9220
|
||
- RAG_SERVICE_URL=http://rag-service:9500
|
||
- MINIO_ENDPOINT=minio:9000
|
||
- MINIO_ACCESS_KEY=minioadmin
|
||
- MINIO_SECRET_KEY=minioadmin
|
||
- MINIO_BUCKET=artifacts
|
||
- MINIO_SECURE=false
|
||
- INDEX_DOC_MAX_BYTES=52428800
|
||
depends_on:
|
||
- nats
|
||
- artifact-registry
|
||
- rag-service
|
||
- minio
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# Brand Registry Service
|
||
brand-registry:
|
||
build:
|
||
context: ./services/brand-registry
|
||
dockerfile: Dockerfile
|
||
container_name: brand-registry-node1
|
||
ports:
|
||
- "9210:9210"
|
||
environment:
|
||
- BRAND_REGISTRY_DATA=/data/brand-registry
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
- brand-registry-data-node1:/data/brand-registry
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:9210/health')\""]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 10s
|
||
|
||
# Brand Intake Service
|
||
brand-intake:
|
||
build:
|
||
context: ./services/brand-intake
|
||
dockerfile: Dockerfile
|
||
container_name: brand-intake-node1
|
||
ports:
|
||
- "9211:9211"
|
||
environment:
|
||
- BRAND_MAP_PATH=/app/config/BrandMap.yaml
|
||
- BRAND_INTAKE_DATA=/data/brand-intake
|
||
- BRAND_REGISTRY_URL=http://brand-registry:9210
|
||
volumes:
|
||
- ./config/brand/BrandMap.yaml:/app/config/BrandMap.yaml:ro
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
- brand-intake-data-node1:/data/brand-intake
|
||
depends_on:
|
||
- brand-registry
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:9211/health')\""]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 10s
|
||
|
||
# Presentation Renderer Service (MVP)
|
||
presentation-renderer:
|
||
build:
|
||
context: ./services/presentation-renderer
|
||
dockerfile: Dockerfile
|
||
container_name: presentation-renderer-node1
|
||
ports:
|
||
- "9212:9212"
|
||
environment:
|
||
- BRAND_REGISTRY_URL=http://brand-registry:9210
|
||
- PRESENTATION_DATA=/data/presentations
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
- presentation-data-node1:/data/presentations
|
||
depends_on:
|
||
- brand-registry
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:9212/health')\""]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 10s
|
||
|
||
# Memory Service
|
||
memory-service:
|
||
build:
|
||
context: ./services/memory-service
|
||
dockerfile: Dockerfile
|
||
container_name: dagi-memory-service-node1
|
||
ports:
|
||
- "8000:8000"
|
||
environment:
|
||
# PostgreSQL connection (uses MEMORY_ prefix as per config.py)
|
||
- MEMORY_POSTGRES_HOST=dagi-postgres
|
||
- MEMORY_POSTGRES_PORT=5432
|
||
- MEMORY_POSTGRES_USER=daarion
|
||
- MEMORY_POSTGRES_PASSWORD=DaarionDB2026!
|
||
- MEMORY_POSTGRES_DB=daarion_memory
|
||
# Qdrant connection
|
||
- MEMORY_QDRANT_HOST=dagi-qdrant-node1
|
||
- MEMORY_QDRANT_PORT=6333
|
||
# Cohere for embeddings
|
||
- MEMORY_COHERE_API_KEY=nOdOXnuepLku2ipJWpe6acWgAsJCsDhMO0RnaEJB
|
||
- MEMORY_DEBUG=false
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
depends_on:
|
||
- qdrant
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/health')\""]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 10s
|
||
|
||
# PostgreSQL (pgvector)
|
||
dagi-postgres:
|
||
image: pgvector/pgvector:pg16
|
||
container_name: dagi-postgres
|
||
ports:
|
||
- "5432:5432"
|
||
environment:
|
||
- POSTGRES_USER=daarion
|
||
- POSTGRES_PASSWORD=DaarionDB2026!
|
||
- POSTGRES_DB=daarion_main
|
||
volumes:
|
||
- postgres_data_node1:/var/lib/postgresql/data
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
|
||
# Qdrant Vector Database
|
||
qdrant:
|
||
image: qdrant/qdrant:v1.7.4
|
||
container_name: dagi-qdrant-node1
|
||
ulimits:
|
||
nofile:
|
||
soft: 65536
|
||
hard: 65536
|
||
ports:
|
||
- "6333:6333" # HTTP API
|
||
- "6334:6334" # gRPC API
|
||
volumes:
|
||
- qdrant-data-node1:/qdrant/storage
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD", "true"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
|
||
# Neo4j Graph Database
|
||
neo4j:
|
||
image: neo4j:5.15-community
|
||
container_name: dagi-neo4j-node1
|
||
ports:
|
||
- "7474:7474" # HTTP
|
||
- "7687:7687" # Bolt
|
||
environment:
|
||
- NEO4J_AUTH=neo4j/DaarionNeo4j2026!
|
||
- NEO4J_PLUGINS=["apoc"]
|
||
- NEO4J_dbms_memory_heap_initial__size=512m
|
||
- NEO4J_dbms_memory_heap_max__size=2G
|
||
volumes:
|
||
- neo4j-data-node1:/data
|
||
- neo4j-logs-node1:/logs
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:7474"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
|
||
# Redis Cache
|
||
redis:
|
||
image: redis:7-alpine
|
||
container_name: dagi-redis-node1
|
||
ports:
|
||
- "6379:6379"
|
||
volumes:
|
||
- redis-data-node1:/data
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD", "redis-cli", "PING"]
|
||
interval: 30s
|
||
timeout: 5s
|
||
retries: 3
|
||
|
||
# Vision Encoder Service - OpenCLIP for text/image embeddings
|
||
vision-encoder:
|
||
build:
|
||
context: ./services/vision-encoder
|
||
dockerfile: Dockerfile
|
||
container_name: dagi-vision-encoder-node1
|
||
ports:
|
||
- "8001:8001"
|
||
environment:
|
||
- DEVICE=cpu # НОДА1 без GPU
|
||
- MODEL_NAME=${VISION_MODEL_NAME:-ViT-L-14}
|
||
- MODEL_PRETRAINED=${VISION_MODEL_PRETRAINED:-openai}
|
||
- NORMALIZE_EMBEDDINGS=true
|
||
- QDRANT_HOST=qdrant
|
||
- QDRANT_PORT=6333
|
||
- QDRANT_ENABLED=true
|
||
volumes:
|
||
- ${DEPLOY_ROOT:-.}/logs:/app/logs
|
||
- vision-model-cache-node1:/root/.cache/clip
|
||
depends_on:
|
||
- qdrant
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\""]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 60s
|
||
|
||
# OCR тепер через Swapper Service (got-ocr2, donut-base, donut-cord моделі)
|
||
|
||
|
||
# Explicit volume names to prevent prefix mismatch
|
||
# This ensures volumes are always named consistently regardless of COMPOSE_PROJECT_NAME
|
||
|
||
# E2E Agent Prober - monitors agent pipeline health
|
||
agent-e2e-prober:
|
||
build:
|
||
context: ./services/agent-e2e-prober
|
||
dockerfile: Dockerfile
|
||
container_name: agent-e2e-prober-node1
|
||
ports:
|
||
- "9108:9108"
|
||
environment:
|
||
- GATEWAY_URL=http://gateway:9300
|
||
- PROBE_INTERVAL=60
|
||
- PROBE_TIMEOUT=30
|
||
- METRICS_PORT=9108
|
||
- SEMANTIC_AGENTS=clan,sofiia,monitor,helion,agromatrix,senpai
|
||
networks:
|
||
- dagi-network
|
||
restart: unless-stopped
|
||
depends_on:
|
||
- gateway
|
||
|
||
# === Market Data Pipeline (added 2026-02-09) ===
|
||
market-data-service:
|
||
container_name: dagi-market-data-node1
|
||
restart: unless-stopped
|
||
build:
|
||
context: ./services/market-data-service
|
||
dockerfile: Dockerfile
|
||
environment:
|
||
- BINANCE_WS_URL=wss://stream.binance.com:9443/ws
|
||
- BYBIT_WS_URL=wss://stream.bybit.com/v5/public/spot
|
||
- ALPACA_DRY_RUN=true
|
||
- SQLITE_URL=sqlite+aiosqlite:////data/market_data.db
|
||
- JSONL_PATH=/data/events.jsonl
|
||
- HTTP_HOST=0.0.0.0
|
||
- HTTP_PORT=8891
|
||
- NATS_URL=nats://nats:4222
|
||
- NATS_ENABLED=true
|
||
- NATS_SUBJECT_PREFIX=md.events
|
||
- LOG_LEVEL=INFO
|
||
- LOG_SAMPLE_RATE=500
|
||
ports:
|
||
- "8893:8891"
|
||
volumes:
|
||
- market-data-node1:/data
|
||
networks:
|
||
- dagi-network
|
||
depends_on:
|
||
- nats
|
||
command: ["run", "--provider", "binance,bybit", "--symbols", "BTCUSDT,ETHUSDT"]
|
||
healthcheck:
|
||
test:
|
||
- CMD-SHELL
|
||
- python -c "import urllib.request; urllib.request.urlopen('http://localhost:8891/health')"
|
||
interval: 15s
|
||
timeout: 5s
|
||
retries: 3
|
||
start_period: 10s
|
||
|
||
senpai-md-consumer:
|
||
container_name: dagi-senpai-md-consumer-node1
|
||
restart: unless-stopped
|
||
build:
|
||
context: ./services/senpai-md-consumer
|
||
dockerfile: Dockerfile
|
||
environment:
|
||
- NATS_URL=nats://nats:4222
|
||
- NATS_SUBJECT=md.events.>
|
||
- NATS_QUEUE_GROUP=senpai-md
|
||
- FEATURES_ENABLED=true
|
||
- FEATURES_PUB_RATE_HZ=10
|
||
- FEATURES_PUB_SUBJECT=senpai.features
|
||
- SIGNALS_PUB_SUBJECT=senpai.signals
|
||
- ALERTS_PUB_SUBJECT=senpai.alerts
|
||
- LOG_LEVEL=INFO
|
||
- HTTP_PORT=8892
|
||
ports:
|
||
- "8892:8892"
|
||
networks:
|
||
- dagi-network
|
||
depends_on:
|
||
nats:
|
||
condition: service_started
|
||
market-data-service:
|
||
condition: service_healthy
|
||
healthcheck:
|
||
test:
|
||
- CMD-SHELL
|
||
- python -c "import urllib.request; urllib.request.urlopen('http://localhost:8892/health')"
|
||
interval: 15s
|
||
timeout: 10s
|
||
retries: 5
|
||
start_period: 15s
|
||
|
||
binance-bot-monitor:
|
||
build:
|
||
context: ./services/binance-bot-monitor
|
||
dockerfile: Dockerfile
|
||
container_name: dagi-binance-bot-monitor-node1
|
||
restart: unless-stopped
|
||
environment:
|
||
- REDIS_URL=redis://redis:6379/0
|
||
- CRAWL4AI_URL=http://crawl4ai:11235
|
||
- SWAPPER_URL=http://swapper-service:8890
|
||
- BINANCE_CACHE_TTL=3600
|
||
- BINANCE_REFRESH_INTERVAL=1800
|
||
- BINANCE_API_KEY=${BINANCE_API_KEY:-}
|
||
- BINANCE_SECRET_KEY=${BINANCE_SECRET_KEY:-}
|
||
networks:
|
||
- dagi-network
|
||
|
||
# ── FarmOS (v4.3 integration) ────────────────────────────────────────────────
|
||
# PostgreSQL для farmOS (окрема БД, не чіпає dagi-postgres)
|
||
dagi-farmos-db-node1:
|
||
image: postgres:16-alpine
|
||
container_name: dagi-farmos-db-node1
|
||
restart: unless-stopped
|
||
environment:
|
||
- POSTGRES_DB=farmos
|
||
- POSTGRES_USER=farmos
|
||
- POSTGRES_PASSWORD=${FARMOS_DB_PASS}
|
||
volumes:
|
||
- farmos-db-data-node1:/var/lib/postgresql/data
|
||
networks:
|
||
- dagi-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "pg_isready -U farmos -d farmos"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 10
|
||
start_period: 15s
|
||
|
||
# farmOS Drupal application (4.x — актуальна стабільна, amd64 для x86_64 сервера)
|
||
dagi-farmos-node1:
|
||
image: farmos/farmos:4.x-amd64
|
||
container_name: dagi-farmos-node1
|
||
restart: unless-stopped
|
||
depends_on:
|
||
dagi-farmos-db-node1:
|
||
condition: service_healthy
|
||
environment:
|
||
- FARMOS_DB_HOST=dagi-farmos-db-node1
|
||
- FARMOS_DB_NAME=farmos
|
||
- FARMOS_DB_USER=farmos
|
||
- FARMOS_DB_PASSWORD=${FARMOS_DB_PASS}
|
||
- FARMOS_DB_DRIVER=pgsql
|
||
volumes:
|
||
- farmos-sites-node1:/opt/drupal/web/sites
|
||
networks:
|
||
- dagi-network
|
||
ports:
|
||
# Доступний тільки локально; для браузерного setup — SSH tunnel: ssh -L 8088:localhost:8088
|
||
- "127.0.0.1:8088:80"
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "curl -fsS http://localhost:80 -o /dev/null || exit 1"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 5
|
||
start_period: 60s
|
||
|
||
|
||
volumes:
|
||
qdrant-data-node1:
|
||
name: qdrant-data-node1
|
||
driver: local
|
||
neo4j-data-node1:
|
||
name: neo4j-data-node1
|
||
driver: local
|
||
neo4j-logs-node1:
|
||
name: neo4j-logs-node1
|
||
driver: local
|
||
redis-data-node1:
|
||
name: redis-data-node1
|
||
driver: local
|
||
vision-model-cache-node1:
|
||
name: vision-model-cache-node1
|
||
driver: local
|
||
docling-model-cache-node1:
|
||
name: docling-model-cache-node1
|
||
driver: local
|
||
swapper-hf-cache-node1:
|
||
name: swapper-hf-cache-node1
|
||
driver: local
|
||
brand-registry-data-node1:
|
||
name: brand-registry-data-node1
|
||
driver: local
|
||
brand-intake-data-node1:
|
||
name: brand-intake-data-node1
|
||
driver: local
|
||
presentation-data-node1:
|
||
name: presentation-data-node1
|
||
driver: local
|
||
nats-data-node1:
|
||
name: nats-data-node1
|
||
driver: local
|
||
minio-data-node1:
|
||
name: minio-data-node1
|
||
driver: local
|
||
postgres_data_node1:
|
||
name: postgres-data-node1
|
||
driver: local
|
||
|
||
market-data-node1:
|
||
name: market-data-node1
|
||
driver: local
|
||
oneok-espocrm-db-node1:
|
||
name: oneok-espocrm-db-node1
|
||
driver: local
|
||
oneok-crm-data-node1:
|
||
name: oneok-crm-data-node1
|
||
driver: local
|
||
|
||
# farmOS persistent volumes (v4.3)
|
||
farmos-db-data-node1:
|
||
name: farmos-db-data-node1
|
||
driver: local
|
||
farmos-sites-node1:
|
||
name: farmos-sites-node1
|
||
driver: local
|
||
|
||
networks:
|
||
dagi-network:
|
||
external: true
|