services: # PostgreSQL Database postgres: image: postgres:15-alpine container_name: autostock-postgres environment: TZ: Asia/Seoul POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - postgres_data:/var/lib/postgresql/data - ./docker/init-db.sql:/docker-entrypoint-initdb.d/init.sql ports: - "127.0.0.1:5432:5432" networks: - autostock-network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 10s timeout: 5s retries: 5 deploy: resources: limits: memory: 1G # Redis Cache redis: image: redis:7-alpine container_name: autostock-redis command: redis-server --requirepass ${REDIS_PASSWORD:-autostock_redis_change_me} --maxmemory 200mb --maxmemory-policy allkeys-lru environment: TZ: Asia/Seoul ports: - "127.0.0.1:6379:6379" volumes: - redis_data:/data networks: - autostock-network healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-autostock_redis_change_me}", "ping"] interval: 10s timeout: 3s retries: 5 deploy: resources: limits: memory: 256M # RabbitMQ Message Queue rabbitmq: image: rabbitmq:3-management container_name: autostock-rabbitmq environment: TZ: Asia/Seoul RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER} RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS} ports: - "127.0.0.1:5672:5672" - "127.0.0.1:15672:15672" volumes: - rabbitmq_data:/var/lib/rabbitmq # - rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf networks: - autostock-network healthcheck: test: rabbitmq-diagnostics -q ping interval: 30s timeout: 10s retries: 5 deploy: resources: limits: memory: 512M # MCP Server mcp-server: build: context: ./mcp-server dockerfile: Dockerfile container_name: autostock-mcp-server environment: - TZ=Asia/Seoul - AI_PROVIDER=${AI_PROVIDER:-claude} - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - GEMINI_API_KEY=${GEMINI_API_KEY} - GEMINI_MODEL=${GEMINI_MODEL:-gemini-2.0-flash} - CLAUDE_MODEL=${CLAUDE_MODEL:-claude-sonnet-4-6-20250514} - CLAUDE_HAIKU_MODEL=${CLAUDE_HAIKU_MODEL:-claude-haiku-4-5-20251001} - HYBRID_AI_ENABLED=${HYBRID_AI_ENABLED:-true} - MCP_API_KEY=${MCP_API_KEY} - MCP_SERVER_HOST=${MCP_SERVER_HOST} - MCP_SERVER_PORT=${MCP_SERVER_PORT} - DATABASE_URL=${DATABASE_URL} - REDIS_URL=${REDIS_URL} - LOG_LEVEL=${LOG_LEVEL} - TOKEN_SAVE_MODE=${TOKEN_SAVE_MODE:-true} ports: - "127.0.0.1:8001:8001" networks: - autostock-network depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped deploy: resources: limits: memory: 256M # Backend API Server backend: build: context: ./backend dockerfile: Dockerfile container_name: autostock-backend environment: - TZ=Asia/Seoul - DATABASE_URL=${DATABASE_URL} - REDIS_URL=${REDIS_URL} - RABBITMQ_URL=${RABBITMQ_URL} - KIS_MODE=${KIS_MODE:-virtual} - KIS_VIRTUAL_APP_KEY=${KIS_VIRTUAL_APP_KEY} - KIS_VIRTUAL_APP_SECRET=${KIS_VIRTUAL_APP_SECRET} - KIS_VIRTUAL_ACCOUNT_NO=${KIS_VIRTUAL_ACCOUNT_NO} - KIS_VIRTUAL_URL=${KIS_VIRTUAL_URL:-https://openapivts.koreainvestment.com:29443} - KIS_REAL_APP_KEY=${KIS_REAL_APP_KEY} - KIS_REAL_APP_SECRET=${KIS_REAL_APP_SECRET} - KIS_REAL_ACCOUNT_NO=${KIS_REAL_ACCOUNT_NO} - KIS_REAL_URL=${KIS_REAL_URL:-https://openapi.koreainvestment.com:9443} - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - GEMINI_API_KEY=${GEMINI_API_KEY} - AI_PROVIDER=${AI_PROVIDER:-claude} - HYBRID_AI_ENABLED=${HYBRID_AI_ENABLED:-true} - API_KEY=${API_KEY:-} - MCP_API_KEY=${MCP_API_KEY:-} - SECRET_KEY=${SECRET_KEY} - BACKEND_HOST=${BACKEND_HOST} - BACKEND_PORT=${BACKEND_PORT} - MCP_SERVER_URL=http://mcp-server:8001 - NEWS_API_KEY=${NEWS_API_KEY:-} - LOG_LEVEL=${LOG_LEVEL} - TOKEN_SAVE_MODE=${TOKEN_SAVE_MODE:-true} - AUTO_TRADE_ENABLED=${AUTO_TRADE_ENABLED:-true} - DAY_TRADE_ENABLED=${DAY_TRADE_ENABLED:-true} - US_TRADING_ENABLED=${US_TRADING_ENABLED:-false} - KIS_WS_ENABLED=${KIS_WS_ENABLED:-true} - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN:-} - TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID:-} ports: - "127.0.0.1:8000:8000" volumes: - ./logs:/logs networks: - autostock-network depends_on: postgres: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy mcp-server: condition: service_started restart: unless-stopped deploy: resources: limits: memory: 768M # PostgreSQL 자동 백업 (매일 02:00 KST, 7일치 보관) postgres-backup: image: prodrigestivill/postgres-backup-local:15 container_name: autostock-postgres-backup environment: - TZ=Asia/Seoul - POSTGRES_HOST=postgres - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - SCHEDULE=0 8,17 * * * - BACKUP_KEEP_DAYS=7 - BACKUP_KEEP_WEEKS=4 - BACKUP_KEEP_MONTHS=3 - HEALTHCHECK_PORT=8080 volumes: - ./backups:/backups networks: - autostock-network depends_on: postgres: condition: service_healthy restart: unless-stopped # Frontend frontend: build: context: ./frontend dockerfile: Dockerfile args: - VITE_API_URL=${VITE_API_URL} - VITE_WS_URL=${VITE_WS_URL} container_name: autostock-frontend environment: - TZ=Asia/Seoul ports: - "127.0.0.1:3000:80" networks: - autostock-network depends_on: - backend restart: unless-stopped deploy: resources: limits: memory: 64M volumes: postgres_data: redis_data: rabbitmq_data: backup_data: networks: autostock-network: driver: bridge