Files
trading/docker-compose.yml
T
kyu 6d3b0bacc0 Initial commit: Korean stock value-investing AI pipeline
- 19개 마이크로서비스 (news-collector, score-engine, ta-engine, dart-collector,
  aux-signal, us-market, graph-engine, telegram-bot, dashboard-api, kis-api 등)
- 가치투자 스코어링 + 10공식 앙상블 보팅 (매직포뮬러/F-Score/Altman/PEG/
  모멘텀/Beneish/GP-A/G-Score/Amihud/BAB)
- 뉴스 수집→형태소→임베딩→중복제거→AI분석 파이프라인
- 기술적분석 + GAT 그래프신경망 + 미증시 동조 시그널

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 21:33:56 +09:00

831 lines
24 KiB
YAML

# ============================================================
# 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"
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:-}"
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
deploy:
resources:
limits:
cpus: "2.0"
memory: 2G
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: 512M
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: 512M
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: 512M
logging: *default-logging