# ============================================================ # Trading AI System # GPU 0: RTX 3060 12GB → Ollama (EXAONE 3.5 추론) # GPU 1: RTX 3070 8GB → Ollama (bge-m3 임베딩) # ============================================================ x-logging: &default-logging driver: "json-file" options: max-size: "${LOG_MAX_SIZE:-100m}" max-file: "${LOG_MAX_FILE:-10}" x-restart: &restart restart: unless-stopped networks: trading-net: driver: bridge ipam: config: - subnet: "${SUBNET:-172.30.0.0/16}" gateway: "${GATEWAY:-172.30.0.1}" volumes: redis-data: qdrant-data: ollama-data: n8n-data: bareun-data: pgdata: services: # ── Phase 1: 네이버 뉴스 수집기 ────────────────────────── news-collector: build: context: ./news-collector dockerfile: Dockerfile container_name: trading-news-collector restart: unless-stopped init: true ports: - "8787:8787" environment: REDIS_HOST: redis REDIS_PASSWORD: "${REDIS_PASSWORD}" POSTGRES_HOST: "${POSTGRES_HOST}" POSTGRES_PORT: "${POSTGRES_PORT}" POSTGRES_DB: "${POSTGRES_DB}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" BAREUN_API_URL: "http://bareunaapi:5757" OLLAMA_URL: "http://ollama:11434" QDRANT_URL: "http://qdrant:6333" GEMINI_API_KEY: "${GEMINI_API_KEY:-}" GEMINI_MODEL: "${GEMINI_MODEL:-gemini-2.5-pro}" TZ: "Asia/Seoul" networks: trading-net: ipv4_address: 172.30.0.16 depends_on: redis: condition: service_healthy bareunaapi: condition: service_healthy postgres: condition: service_healthy deploy: resources: limits: cpus: "2.0" memory: 2G healthcheck: test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:8787/health')\" 2>/dev/null || exit 1"] interval: 30s timeout: 10s retries: 5 start_period: 30s logging: driver: "json-file" options: max-size: "100m" max-file: "5" # ── Phase 2: 한국투자증권 주가 API ────────────────────── kis-api: build: context: ./kis-api dockerfile: Dockerfile container_name: trading-kis-api restart: unless-stopped init: true ports: - "8585:8585" environment: KIWOOM_APP_KEY: "${KIWOOM_APP_KEY}" KIWOOM_SECRET_KEY: "${KIWOOM_SECRET_KEY}" KIWOOM_BASE_URL: "${KIWOOM_BASE_URL:-https://api.kiwoom.com}" REDIS_HOST: redis REDIS_PASSWORD: "${REDIS_PASSWORD}" POSTGRES_HOST: "${POSTGRES_HOST}" POSTGRES_PORT: "${POSTGRES_PORT}" POSTGRES_DB: "${POSTGRES_DB}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" TZ: "Asia/Seoul" networks: trading-net: ipv4_address: 172.30.0.18 depends_on: redis: condition: service_healthy postgres: condition: service_healthy deploy: resources: limits: cpus: "2.0" memory: 1G healthcheck: test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:8585/health')\" 2>/dev/null || exit 1"] interval: 30s timeout: 10s retries: 5 start_period: 30s logging: driver: "json-file" options: max-size: "50m" max-file: "5" # ── Phase 2.5: 기술적 분석 엔진 ────────────────────────── ta-engine: build: context: ./ta-engine dockerfile: Dockerfile container_name: trading-ta-engine restart: unless-stopped init: true ports: - "8484:8484" environment: REDIS_HOST: redis REDIS_PASSWORD: "${REDIS_PASSWORD}" POSTGRES_HOST: "${POSTGRES_HOST}" POSTGRES_PORT: "${POSTGRES_PORT}" POSTGRES_DB: "${POSTGRES_DB}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" OLLAMA_URL: "http://ollama:11434" TZ: "Asia/Seoul" networks: trading-net: ipv4_address: 172.30.0.23 depends_on: redis: condition: service_healthy postgres: condition: service_healthy deploy: resources: limits: cpus: "2.0" memory: 1G healthcheck: test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:8484/health')\" 2>/dev/null || exit 1"] interval: 30s timeout: 10s retries: 5 start_period: 30s logging: driver: "json-file" options: max-size: "50m" max-file: "5" # ── Phase 3: 종목 점수 엔진 ───────────────────────────── score-engine: build: context: ./score-engine dockerfile: Dockerfile container_name: trading-score-engine restart: unless-stopped init: true ports: - "8686:8686" environment: REDIS_HOST: redis REDIS_PASSWORD: "${REDIS_PASSWORD}" POSTGRES_HOST: "${POSTGRES_HOST}" POSTGRES_PORT: "${POSTGRES_PORT}" POSTGRES_DB: "${POSTGRES_DB}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" TELEGRAM_BOT_TOKEN: "${TELEGRAM_BOT_TOKEN:-}" TELEGRAM_CHAT_ID: "${TELEGRAM_CHAT_ID:-}" ECOS_API_KEY: "${ECOS_API_KEY:-}" GEMINI_API_KEY: "${GEMINI_API_KEY:-}" GEMINI_MODEL: "${GEMINI_MODEL:-gemini-2.5-pro}" TRADE_DEFAULT_CAPITAL: "${TRADE_DEFAULT_CAPITAL:-10000000}" TZ: "Asia/Seoul" networks: trading-net: ipv4_address: 172.30.0.19 depends_on: redis: condition: service_healthy ta-engine: condition: service_healthy postgres: condition: service_healthy deploy: resources: limits: cpus: "2.0" memory: 1G healthcheck: test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:8686/health')\" 2>/dev/null || exit 1"] interval: 30s timeout: 10s retries: 5 start_period: 30s logging: driver: "json-file" options: max-size: "50m" max-file: "5" # ── Phase 3.7: 텔레그램 양방향 봇 ─────────────────────── telegram-bot: build: context: ./telegram-bot dockerfile: Dockerfile container_name: trading-telegram-bot restart: unless-stopped environment: POSTGRES_HOST: "${POSTGRES_HOST}" POSTGRES_PORT: "${POSTGRES_PORT}" POSTGRES_DB: "${POSTGRES_DB}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" TELEGRAM_BOT_TOKEN: "${TELEGRAM_BOT_TOKEN}" TELEGRAM_CHAT_ID: "${TELEGRAM_CHAT_ID}" OLLAMA_URL: "http://ollama:11434" EXAONE_MODEL: "exaone3.5:7.8b" TZ: "Asia/Seoul" networks: trading-net: ipv4_address: 172.30.0.26 depends_on: postgres: condition: service_healthy deploy: resources: limits: cpus: "1.0" memory: 512M logging: driver: "json-file" options: max-size: "50m" max-file: "5" # ── Phase 3.6: 보조 시그널 (컨센서스/기관수급/매크로) ── aux-signal: build: context: ./aux-signal dockerfile: Dockerfile container_name: trading-aux-signal restart: unless-stopped init: true ports: - "8282:8282" environment: POSTGRES_HOST: "${POSTGRES_HOST}" POSTGRES_PORT: "${POSTGRES_PORT}" POSTGRES_DB: "${POSTGRES_DB}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" ECOS_API_KEY: "${ECOS_API_KEY:-}" TZ: "Asia/Seoul" networks: trading-net: ipv4_address: 172.30.0.25 depends_on: postgres: condition: service_healthy deploy: resources: limits: cpus: "2.0" memory: 1G healthcheck: test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:8282/health')\" 2>/dev/null || exit 1"] interval: 30s timeout: 10s retries: 5 start_period: 60s logging: driver: "json-file" options: max-size: "50m" max-file: "5" # ── Phase 3.5: 미국증시 동조 시그널 ───────────────────── us-market: build: context: ./us-market dockerfile: Dockerfile container_name: trading-us-market restart: unless-stopped init: true ports: - "8383:8383" environment: POSTGRES_HOST: "${POSTGRES_HOST}" POSTGRES_PORT: "${POSTGRES_PORT}" POSTGRES_DB: "${POSTGRES_DB}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" FINNHUB_API_KEY: "${FINNHUB_API_KEY:-}" ALPHAVANTAGE_API_KEY: "${ALPHAVANTAGE_API_KEY:-}" TZ: "Asia/Seoul" networks: trading-net: ipv4_address: 172.30.0.24 depends_on: postgres: condition: service_healthy deploy: resources: limits: cpus: "2.0" memory: 1G healthcheck: test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:8383/health')\" 2>/dev/null || exit 1"] interval: 30s timeout: 10s retries: 5 start_period: 60s logging: driver: "json-file" options: max-size: "50m" max-file: "5" # ── Phase 5: 그래프 신경망 (GAT) ──────────────────────── graph-engine: build: context: ./graph-engine dockerfile: Dockerfile container_name: trading-graph-engine restart: unless-stopped init: true ports: - "9090:9090" environment: POSTGRES_HOST: "${POSTGRES_HOST}" POSTGRES_PORT: "${POSTGRES_PORT}" POSTGRES_DB: "${POSTGRES_DB}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" GRAPH_MODEL_DIR: "/mnt/nas/models/graph" TZ: "Asia/Seoul" volumes: - /mnt/nas/models:/mnt/nas/models networks: trading-net: ipv4_address: 172.30.0.27 depends_on: postgres: condition: service_healthy deploy: resources: limits: cpus: "4.0" memory: 4G healthcheck: test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:9090/health')\" 2>/dev/null || exit 1"] interval: 30s timeout: 10s retries: 5 start_period: 90s logging: driver: "json-file" options: max-size: "50m" max-file: "5" # ── Phase 4: 대시보드 API ─────────────────────────────── dashboard-api: build: context: ./dashboard-api dockerfile: Dockerfile container_name: trading-dashboard-api restart: unless-stopped init: true ports: - "8989:8989" environment: REDIS_HOST: redis REDIS_PASSWORD: "${REDIS_PASSWORD}" POSTGRES_HOST: "${POSTGRES_HOST}" POSTGRES_PORT: "${POSTGRES_PORT}" POSTGRES_DB: "${POSTGRES_DB}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" JWT_SECRET: "${JWT_SECRET}" JWT_EXPIRE_DAYS: "${JWT_EXPIRE_DAYS}" ADMIN_EMAILS: "${ADMIN_EMAILS}" TRUSTED_ORIGINS: "${TRUSTED_ORIGINS}" TZ: "Asia/Seoul" networks: trading-net: ipv4_address: 172.30.0.22 depends_on: redis: condition: service_healthy postgres: condition: service_healthy deploy: resources: limits: cpus: "2.0" memory: 1G healthcheck: test: ["CMD-SHELL", "true"] interval: 30s timeout: 10s retries: 3 start_period: 15s logging: driver: "json-file" options: max-size: "50m" max-file: "5" # ────────────────────────────────────────── # DART 공시 수집기 172.30.0.17 # ────────────────────────────────────────── dart-collector: build: context: ./dart-collector dockerfile: Dockerfile container_name: trading-dart-collector restart: unless-stopped init: true ports: - "8888:8888" environment: DART_API_KEY: "${DART_API_KEY}" REDIS_HOST: redis REDIS_PASSWORD: "${REDIS_PASSWORD}" POSTGRES_HOST: "${POSTGRES_HOST}" POSTGRES_PORT: "${POSTGRES_PORT}" POSTGRES_DB: "${POSTGRES_DB}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" BAREUN_API_URL: "http://bareunaapi:5757" OLLAMA_URL: "http://ollama:11434" QDRANT_URL: "http://qdrant:6333" TZ: "Asia/Seoul" N8N_EDITOR_BASE_URL: "https://n8.kyleyang.co.kr" WEBHOOK_URL: "https://n8.kyleyang.co.kr" N8N_HOST: "0.0.0.0" N8N_LISTEN_ADDRESS: "0.0.0.0" networks: trading-net: ipv4_address: 172.30.0.17 depends_on: redis: condition: service_healthy bareunaapi: condition: service_healthy postgres: condition: service_healthy deploy: resources: limits: cpus: "2.0" memory: 2G healthcheck: test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:8888/health')\" 2>/dev/null || exit 1"] interval: 30s timeout: 10s retries: 5 start_period: 60s logging: driver: "json-file" options: max-size: "100m" max-file: "10" # ────────────────────────────────────────── # ────────────────────────────────────────── # PostgreSQL 172.30.0.9 # ────────────────────────────────────────── postgres: image: postgres:16 container_name: trading-postgres <<: *restart ports: - "55432:5432" environment: POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" POSTGRES_DB: "${POSTGRES_DB}" PGDATA: /var/lib/postgresql/data TZ: "Asia/Seoul" volumes: - pgdata:/var/lib/postgresql/data - ./init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro networks: trading-net: ipv4_address: 172.30.0.9 # ── 메모리 튜닝 (32GB 호스트, 로컬 SSD 기준) ── # shared_buffers 4GB (컨테이너 limit의 ~67% — Postgres hot cache) # effective_cache_size 12GB (OS 페이지캐시 포함 추정 가용 캐시) # work_mem 32MB (단일 sort/hash 메모리. max_conn × 동시쿼리 곱 주의) # maintenance_work_mem 512MB (VACUUM/CREATE INDEX) # random_page_cost 1.1 (SSD 비용 모델) # effective_io_concurrency 200 (SSD) # parallel_workers 병렬쿼리 활성화 (백테스트/학습용 큰 JOIN에 효과) # WAL/checkpoint 쓰기 부하 줄이고 회복 시간 살짝 늘림 (적절 균형) command: > postgres -c shared_buffers=4GB -c effective_cache_size=12GB -c work_mem=32MB -c maintenance_work_mem=512MB -c random_page_cost=1.1 -c effective_io_concurrency=200 -c max_parallel_workers_per_gather=4 -c max_parallel_workers=8 -c max_worker_processes=12 -c checkpoint_timeout=15min -c max_wal_size=4GB -c checkpoint_completion_target=0.9 -c wal_compression=on -c log_min_duration_statement=1000 -c log_checkpoints=on -c log_temp_files=10MB -c jit=off shm_size: 512mb deploy: resources: limits: cpus: "4.0" memory: 12G healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 start_period: 30s logging: *default-logging # Redis 172.30.0.10 # ────────────────────────────────────────── redis: image: redis:7.2-alpine container_name: trading-redis <<: *restart command: > redis-server --requirepass ${REDIS_PASSWORD} --maxmemory ${REDIS_MAX_MEMORY:-2gb} --maxmemory-policy ${REDIS_MAXMEMORY_POLICY:-allkeys-lru} --save 900 1 --save 300 10 --appendonly yes --appendfsync everysec --tcp-keepalive 300 ports: - "6379:6379" volumes: - redis-data:/data networks: trading-net: ipv4_address: 172.30.0.10 deploy: resources: limits: cpus: "2.0" memory: 1G healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] interval: 10s timeout: 5s retries: 5 start_period: 10s logging: *default-logging # ────────────────────────────────────────── # Qdrant 172.30.0.11 # ────────────────────────────────────────── qdrant: image: qdrant/qdrant:v1.9.2 container_name: trading-qdrant <<: *restart ports: - "6333:6333" - "6334:6334" volumes: - qdrant-data:/qdrant/storage - ./qdrant-config/config.yaml:/qdrant/config/production.yaml:ro environment: QDRANT__SERVICE__HTTP_PORT: 6333 QDRANT__SERVICE__GRPC_PORT: 6334 QDRANT__LOG_LEVEL: INFO networks: trading-net: ipv4_address: 172.30.0.11 deploy: resources: limits: cpus: "4.0" memory: 1G healthcheck: test: ["CMD-SHELL", "true"] interval: 10s timeout: 5s retries: 3 start_period: 10s logging: *default-logging # ────────────────────────────────────────── # Bareun 형태소 엔진 172.30.0.15 # ────────────────────────────────────────── bareun: image: bareunai/bareun:latest container_name: trading-bareun <<: *restart ports: - "5656:5656" - "9902:9902" volumes: - bareun-data:/bareun/var networks: trading-net: ipv4_address: 172.30.0.15 deploy: resources: limits: cpus: "4.0" memory: 1500M reservations: memory: 512M healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:9902/health || exit 0"] interval: 20s timeout: 10s retries: 5 start_period: 30s logging: *default-logging # ────────────────────────────────────────── # 바른 API (FastAPI 래퍼) 172.30.0.12 # ────────────────────────────────────────── bareunaapi: build: context: ./bareunaapi dockerfile: Dockerfile container_name: trading-bareunaapi <<: *restart ports: - "5757:5757" environment: BAREUN_API_KEY: "${BAREUN_API_KEY}" BAREUN_SERVER_HOST: bareun BAREUN_SERVER_PORT: 5656 REDIS_HOST: redis REDIS_PORT: 6379 REDIS_PASSWORD: "${REDIS_PASSWORD}" REDIS_DB: 1 NEWS_DEDUP_TTL: "${NEWS_DEDUP_TTL:-86400}" LOG_LEVEL: INFO networks: trading-net: ipv4_address: 172.30.0.12 depends_on: redis: condition: service_healthy bareun: condition: service_started deploy: resources: limits: cpus: "4.0" memory: 1G healthcheck: test: ["CMD", "curl", "-f", "http://localhost:5757/health"] interval: 15s timeout: 10s retries: 5 start_period: 40s logging: *default-logging # ────────────────────────────────────────── # Ollama 추론+임베딩 (GPU 0+1) 172.30.0.13 # GPU 0: RTX 3060 12GB → EXAONE 3.5 7.8B 추론 # GPU 1: RTX 3070 8GB → bge-m3 임베딩 # ────────────────────────────────────────── ollama: image: ollama/ollama:latest container_name: trading-ollama <<: *restart ports: - "11434:11434" volumes: - ollama-data:/root/.ollama environment: OLLAMA_NUM_PARALLEL: "${OLLAMA_NUM_PARALLEL:-4}" OLLAMA_MAX_LOADED_MODELS: "2" OLLAMA_FLASH_ATTENTION: "1" CUDA_VISIBLE_DEVICES: "0,1" networks: trading-net: ipv4_address: 172.30.0.13 deploy: resources: limits: cpus: "8.0" memory: 24G reservations: devices: - driver: nvidia device_ids: ["0", "1"] capabilities: [gpu] healthcheck: test: ["CMD-SHELL", "true"] interval: 10s timeout: 5s retries: 3 start_period: 10s logging: *default-logging # ────────────────────────────────────────── # n8n 워크플로우 172.30.0.20 # ────────────────────────────────────────── n8n: image: n8nio/n8n:latest container_name: trading-n8n <<: *restart ports: - "5678:5678" environment: N8N_BASIC_AUTH_ACTIVE: "true" N8N_BASIC_AUTH_USER: "${N8N_BASIC_AUTH_USER}" N8N_BASIC_AUTH_PASSWORD: "${N8N_BASIC_AUTH_PASSWORD}" N8N_ENCRYPTION_KEY: "${N8N_ENCRYPTION_KEY}" WEBHOOK_URL: "${N8N_WEBHOOK_URL}" N8N_LOG_LEVEL: info N8N_METRICS: "true" # DB - NAS PostgreSQL DB_TYPE: postgresdb DB_POSTGRESDB_HOST: "${POSTGRES_HOST}" DB_POSTGRESDB_PORT: "${POSTGRES_PORT:-5432}" DB_POSTGRESDB_DATABASE: "${POSTGRES_DB}" DB_POSTGRESDB_USER: "${POSTGRES_USER}" DB_POSTGRESDB_PASSWORD: "${POSTGRES_PASSWORD}" DB_POSTGRESDB_SCHEMA: n8n DB_POSTGRESDB_POOL_SIZE: "10" DB_POSTGRESDB_CONNECT_TIMEOUT: "30000" # Redis Queue QUEUE_BULL_REDIS_HOST: redis QUEUE_BULL_REDIS_PORT: 6379 QUEUE_BULL_REDIS_PASSWORD: "${REDIS_PASSWORD}" QUEUE_BULL_REDIS_DB: 0 EXECUTIONS_MODE: queue N8N_GRACEFUL_SHUTDOWN_TIMEOUT: 30 TZ: "${TZ:-Asia/Seoul}" GENERIC_TIMEZONE: "${TZ:-Asia/Seoul}" # 내부 서비스 주소 (워크플로우에서 사용) BAREUNAAPI_URL: "http://bareunaapi:5757" OLLAMA_URL: "http://ollama:11434" QDRANT_URL: "http://qdrant:6333" REDIS_PASSWORD: "${REDIS_PASSWORD}" POSTGRES_HOST: "${POSTGRES_HOST}" POSTGRES_DB: "${POSTGRES_DB}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" NEWS_SIMILARITY_THRESHOLD: "${NEWS_SIMILARITY_THRESHOLD:-0.92}" TELEGRAM_BOT_TOKEN: "${TELEGRAM_BOT_TOKEN:-}" TELEGRAM_CHAT_ID: "${TELEGRAM_CHAT_ID:-}" N8N_SECURE_COOKIE: "false" # 실행 이력 자동 정리 (느린 n8n 해결) EXECUTIONS_DATA_PRUNE: "true" EXECUTIONS_DATA_MAX_AGE: 168 EXECUTIONS_DATA_PRUNE_MAX_COUNT: 10000 volumes: - n8n-data:/home/node/.n8n - /mnt/nas:/mnt/nas networks: trading-net: ipv4_address: 172.30.0.20 depends_on: redis: condition: service_healthy qdrant: condition: service_healthy bareunaapi: condition: service_healthy postgres: condition: service_healthy deploy: resources: limits: cpus: "4.0" memory: 1G healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:5678/healthz"] interval: 30s timeout: 10s retries: 5 start_period: 60s logging: *default-logging # ────────────────────────────────────────── # n8n Worker 172.30.0.21 # ────────────────────────────────────────── n8n-worker: image: n8nio/n8n:latest container_name: trading-n8n-worker <<: *restart command: worker environment: N8N_ENCRYPTION_KEY: "${N8N_ENCRYPTION_KEY}" DB_TYPE: postgresdb DB_POSTGRESDB_HOST: "${POSTGRES_HOST}" DB_POSTGRESDB_PORT: "${POSTGRES_PORT:-5432}" DB_POSTGRESDB_DATABASE: "${POSTGRES_DB}" DB_POSTGRESDB_USER: "${POSTGRES_USER}" DB_POSTGRESDB_PASSWORD: "${POSTGRES_PASSWORD}" DB_POSTGRESDB_SCHEMA: n8n DB_POSTGRESDB_POOL_SIZE: "5" DB_POSTGRESDB_CONNECT_TIMEOUT: "30000" QUEUE_BULL_REDIS_HOST: redis QUEUE_BULL_REDIS_PORT: 6379 QUEUE_BULL_REDIS_PASSWORD: "${REDIS_PASSWORD}" QUEUE_BULL_REDIS_DB: 0 EXECUTIONS_MODE: queue TZ: "${TZ:-Asia/Seoul}" GENERIC_TIMEZONE: "${TZ:-Asia/Seoul}" BAREUNAAPI_URL: "http://bareunaapi:5757" OLLAMA_URL: "http://ollama:11434" QDRANT_URL: "http://qdrant:6333" REDIS_PASSWORD: "${REDIS_PASSWORD}" volumes: - n8n-data:/home/node/.n8n - /mnt/nas:/mnt/nas networks: trading-net: ipv4_address: 172.30.0.21 depends_on: - n8n deploy: resources: limits: cpus: "4.0" memory: 1G logging: *default-logging