{"repo": "cetangzhi/flowainew", "files": {"docker-compose.dev.yml": {"94cc7095db1259c5f1cb053bdf5c74bb0c4c16c3": {"t": 1785745252.069727, "n": 11921, "h": "2b79e7fab732f2f5", "c": "services:\n # ==================== Infrastructure Services ====================\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n env_file:\n - .env\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n ports:\n - \"5432:5432\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"pg_isready -U postgres\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n ports:\n - \"6379:6379\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n volumes:\n - /data/qdrant:/qdrant/storage\n ports:\n - \"6333:6333\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"grep -q ':18BD' /proc/net/tcp*\" ]\n interval: 10s\n timeout: 5s\n retries: 10\n start_period: 20s\n\n # ==================== 1. 调度分发器 (Dispatcher) ====================\n # 替代原有的单体 Polling Scheduler\n # 职责: 扫描数据库,将任务分发给 Celery Worker\n # 使用轻量级镜像(无AI依赖)\n bot-dispatcher:\n build:\n context: ./backend\n dockerfile: Dockerfile.dispatcher\n container_name: flowai-dispatcher\n command: python3 -m app.services.bot_scheduler\n env_file:\n - .env\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n - postgres\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f bot_scheduler || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 2. 行情总线 (Market Data Bus) ====================\n # 职责: 维护 WebSocket 长连接,将实时行情推送到 Redis\n market-publisher:\n build: ./backend\n container_name: flowai-market-pub\n command: python3 -m app.services.market_data_publisher\n env_file:\n - .env\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n # 如果需要 API Key (通常 WebSocket 公共频道不需要)\n # - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f market_data_publisher || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 3. 独立风控 (Risk Sidecar) ====================\n # 职责: 独立守护进程,监控账户净值与 Bot 亏损,执行熔断\n risk-monitor:\n build: ./backend\n container_name: flowai-risk-monitor\n command: python3 -m app.services.risk_monitor\n env_file:\n - .env\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n depends_on:\n - postgres\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f risk_monitor || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 4. 交易执行器 (Celery Workers) ====================\n # 职责: 消费任务队列,执行具体的交易决策与下单\n # 可以通过 --scale trading-worker=N 进行水平扩展\n trading-worker:\n build:\n context: ./backend\n container_name: flowai-trading-worker\n command: celery -A app.celery_app worker --loglevel=info -Q trading --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n env_file:\n - .env\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - USE_DYNAMIC_TOOLS=${USE_DYNAMIC_TOOLS:-true}\n - TOOL_TIMEOUT_TIER1=${TOOL_TIMEOUT_TIER1:-30}\n - TOOL_TIMEOUT_TIER2=${TOOL_TIMEOUT_TIER2:-10}\n - TOOL_TIMEOUT_TIER3=${TOOL_TIMEOUT_TIER3:-5}\n - TOOL_HEALTH_THRESHOLD=${TOOL_HEALTH_THRESHOLD:-0.5}\n depends_on:\n - postgres\n - redis\n - qdrant\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 2G\n\n celery-worker:\n image: flowainew-trading-worker\n container_name: flowai-celery-worker\n command: celery -A app.celery_app worker --loglevel=info -Q celery --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n env_file:\n - .env\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - USE_DYNAMIC_TOOLS=${USE_DYNAMIC_TOOLS:-true}\n - TOOL_TIMEOUT_TIER1=${TOOL_TIMEOUT_TIER1:-30}\n - TOOL_TIMEOUT_TIER2=${TOOL_TIMEOUT_TIER2:-10}\n - TOOL_TIMEOUT_TIER3=${TOOL_TIMEOUT_TIER3:-5}\n - TOOL_HEALTH_THRESHOLD=${TOOL_HEALTH_THRESHOLD:-0.5}\n depends_on:\n - postgres\n - redis\n - qdrant\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 2G\n\n # ==================== 5. Celery Beat 定时任务调度器 ====================\n # 职责: 执行定时任务(如每日策略复盘、数据爬取等)\n # Phase 3: 每日策略进化复盘任务依赖此服务\n celery-beat:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-beat\n command: celery -A app.celery_app beat --loglevel=info\n\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n env_file:\n - .env\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n - USE_DYNAMIC_TOOLS=${USE_DYNAMIC_TOOLS:-true}\n - TOOL_TIMEOUT_TIER1=${TOOL_TIMEOUT_TIER1:-30}\n - TOOL_TIMEOUT_TIER2=${TOOL_TIMEOUT_TIER2:-10}\n - TOOL_TIMEOUT_TIER3=${TOOL_TIMEOUT_TIER3:-5}\n - TOOL_HEALTH_THRESHOLD=${TOOL_HEALTH_THRESHOLD:-0.5}\n depends_on:\n - postgres\n - redis\n - qdrant\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f 'celery.*beat' || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '0.25'\n memory: 512M\n\n # ==================== FinRL 服务 ====================\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: unless-stopped\n volumes:\n - /data/finrl/models:/models\n ports:\n - \"8001:8001\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 4G\n\n # ==================== Market Data Microservice ====================\n market-service:\n build:\n context: ./backend/microservices/market\n dockerfile: Dockerfile\n container_name: crypto-ai-market-service\n restart: unless-stopped\n ports:\n - \"8002:8000\"\n env_file:\n - .env\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n - EXCHANGE_API_SECRET=${EXCHANGE_API_SECRET}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 1G\n\n # ==================== Backend API 服务 ====================\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n env_file:\n - .env\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - FINRL_SERVICE_URL=http://finrl:8001\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n - JWT_SECRET_KEY=${JWT_SECRET_KEY}\n - ENVIRONMENT=development\n - USE_DYNAMIC_TOOLS=${USE_DYNAMIC_TOOLS:-true}\n - TOOL_TIMEOUT_TIER1=${TOOL_TIMEOUT_TIER1:-30}\n - TOOL_TIMEOUT_TIER2=${TOOL_TIMEOUT_TIER2:-10}\n - TOOL_TIMEOUT_TIER3=${TOOL_TIMEOUT_TIER3:-5}\n - TOOL_HEALTH_THRESHOLD=${TOOL_HEALTH_THRESHOLD:-0.5}\n - CUDA_VISIBLE_DEVICES=\n depends_on:\n - postgres\n - redis\n - qdrant\n - finrl\n networks:\n - crypto-ai-network\n restart: unless-stopped\n ports:\n - \"8100:8000\"\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '0.25'\n memory: 512M\n\n # ==================== 新增:Frontend UI 服务 ====================\n frontend:\n # 生产模式构建\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n # 浏览器通过 /api 前缀访问后端,由 Nginx / Next.js 反向代理\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n container_name: crypto-ai-frontend\n restart: unless-stopped\n env_file:\n - .env\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n NODE_ENV: production\n ports:\n - \"3000:3000\"\n networks:\n - crypto-ai-network\n deploy:\n resources:\n limits:\n cpus: '2.0'\n memory: 6G\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n"}, "e2a9d134ea09324bc8ad87e826e5c83e34830734": {"t": 1785749253.1634133, "n": 12328, "h": "758c277bfd44f496", "c": "services:\n # ==================== Infrastructure Services ====================\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n ports:\n - \"5432:5432\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"pg_isready -U postgres\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n ports:\n - \"6379:6379\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n volumes:\n - /data/qdrant:/qdrant/storage\n ports:\n - \"6333:6333\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"grep -q ':18BD' /proc/net/tcp*\" ]\n interval: 10s\n timeout: 5s\n retries: 10\n start_period: 20s\n\n # ==================== 1. 调度分发器 (Dispatcher) ====================\n # 替代原有的单体 Polling Scheduler\n # 职责: 扫描数据库,将任务分发给 Celery Worker\n # 使用轻量级镜像(无AI依赖)\n bot-dispatcher:\n build:\n context: ./backend\n dockerfile: Dockerfile.dispatcher\n container_name: flowai-dispatcher\n command: python3 -m app.services.bot_scheduler\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n - postgres\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f bot_scheduler || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 2. 行情总线 (Market Data Bus) ====================\n # 职责: 维护 WebSocket 长连接,将实时行情推送到 Redis\n market-publisher:\n build: ./backend\n container_name: flowai-market-pub\n command: python3 -m app.services.market_data_publisher\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n # 如果需要 API Key (通常 WebSocket 公共频道不需要)\n # - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f market_data_publisher || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 3. 独立风控 (Risk Sidecar) ====================\n # 职责: 独立守护进程,监控账户净值与 Bot 亏损,执行熔断\n risk-monitor:\n build: ./backend\n container_name: flowai-risk-monitor\n command: python3 -m app.services.risk_monitor\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n depends_on:\n - postgres\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f risk_monitor || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 4. 交易执行器 (Celery Workers) ====================\n # 职责: 消费任务队列,执行具体的交易决策与下单\n # 可以通过 --scale trading-worker=N 进行水平扩展\n trading-worker:\n build:\n context: ./backend\n container_name: flowai-trading-worker\n command: celery -A app.celery_app worker --loglevel=info -Q trading,celery --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - USE_DYNAMIC_TOOLS=${USE_DYNAMIC_TOOLS:-true}\n - TOOL_TIMEOUT_TIER1=${TOOL_TIMEOUT_TIER1:-30}\n - TOOL_TIMEOUT_TIER2=${TOOL_TIMEOUT_TIER2:-10}\n - TOOL_TIMEOUT_TIER3=${TOOL_TIMEOUT_TIER3:-5}\n - TOOL_HEALTH_THRESHOLD=${TOOL_HEALTH_THRESHOLD:-0.5}\n depends_on:\n - postgres\n - redis\n - qdrant\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 2G\n\n # ==================== 5. Celery Beat 定时任务调度器 ====================\n # 职责: 执行定时任务(如每日策略复盘、数据爬取等)\n # Phase 3: 每日策略进化复盘任务依赖此服务\n celery-beat:\n<<<<<<< HEAD\n build:\n=======\n build: \n>>>>>>> 73439532426f5539ba2fb68eb91e077cfb542b08\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-beat\n command: celery -A app.celery_app beat --loglevel=info\n<<<<<<< HEAD\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n - USE_DYNAMIC_TOOLS=${USE_DYNAMIC_TOOLS:-true}\n - TOOL_TIMEOUT_TIER1=${TOOL_TIMEOUT_TIER1:-30}\n - TOOL_TIMEOUT_TIER2=${TOOL_TIMEOUT_TIER2:-10}\n - TOOL_TIMEOUT_TIER3=${TOOL_TIMEOUT_TIER3:-5}\n - TOOL_HEALTH_THRESHOLD=${TOOL_HEALTH_THRESHOLD:-0.5}\n depends_on:\n - postgres\n - redis\n - qdrant\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f 'celery.*beat' || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '0.25'\n memory: 512M\n\n # ==================== FinRL 服务 ====================\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: unless-stopped\n volumes:\n - /data/finrl/models:/models\n ports:\n - \"8001:8001\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 4G\n\n # ==================== Market Data Microservice ====================\n market-service:\n build:\n context: ./backend/microservices/market\n dockerfile: Dockerfile\n container_name: crypto-ai-market-service\n restart: unless-stopped\n ports:\n - \"8002:8000\"\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n - EXCHANGE_API_SECRET=${EXCHANGE_API_SECRET}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 1G\n\n # ==================== Backend API 服务 ====================\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n=======\n>>>>>>> 73439532426f5539ba2fb68eb91e077cfb542b08\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - FINRL_SERVICE_URL=http://finrl:8001\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n - JWT_SECRET_KEY=${JWT_SECRET_KEY}\n - ENVIRONMENT=development\n - USE_DYNAMIC_TOOLS=${USE_DYNAMIC_TOOLS:-true}\n - TOOL_TIMEOUT_TIER1=${TOOL_TIMEOUT_TIER1:-30}\n - TOOL_TIMEOUT_TIER2=${TOOL_TIMEOUT_TIER2:-10}\n - TOOL_TIMEOUT_TIER3=${TOOL_TIMEOUT_TIER3:-5}\n - TOOL_HEALTH_THRESHOLD=${TOOL_HEALTH_THRESHOLD:-0.5}\n depends_on:\n - postgres\n - redis\n - qdrant\n - finrl\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n<<<<<<< HEAD\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n=======\n test: [\"CMD-SHELL\", \"pgrep -f 'celery.*beat' || exit 1\"]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '0.25'\n memory: 512M\n\n # ==================== FinRL 服务 ====================\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: unless-stopped\n volumes:\n - /data/finrl/models:/models\n ports:\n - \"8001:8001\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 4G\n\n # ==================== Backend API 服务 ====================\n backend:\n build: \n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n ports:\n - \"8000:8000\"\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - FINRL_SERVICE_URL=http://finrl:8001\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n - JWT_SECRET_KEY=${JWT_SECRET_KEY}\n - ENVIRONMENT=development\n depends_on:\n - postgres\n - redis\n - qdrant\n - finrl\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\"]\n>>>>>>> 73439532426f5539ba2fb68eb91e077cfb542b08\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 2G\n\n # ==================== 新增:Frontend UI 服务 ====================\n frontend:\n # 生产模式构建\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n # 浏览器通过 /api 前缀访问后端,由 Nginx / Next.js 反向代理\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n container_name: crypto-ai-frontend\n restart: unless-stopped\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n NODE_ENV: production\n ports:\n - \"3000:3000\"\n networks:\n - crypto-ai-network\n deploy:\n resources:\n limits:\n cpus: '2.0'\n memory: 6G\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n"}, "7fe52b597687befcd02e3cb00104c28bdb689766": {"t": 1785749254.4065413, "n": 10345, "h": "c97386b0b4fda974", "c": "services:\n # ==================== Infrastructure Services ====================\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n ports:\n - \"5432:5432\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"pg_isready -U postgres\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n ports:\n - \"6379:6379\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n volumes:\n - /data/qdrant:/qdrant/storage\n ports:\n - \"6333:6333\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"grep -q ':18BD' /proc/net/tcp*\" ]\n interval: 10s\n timeout: 5s\n retries: 10\n start_period: 20s\n\n # ==================== 1. 调度分发器 (Dispatcher) ====================\n # 替代原有的单体 Polling Scheduler\n # 职责: 扫描数据库,将任务分发给 Celery Worker\n # 使用轻量级镜像(无AI依赖)\n bot-dispatcher:\n build:\n context: ./backend\n dockerfile: Dockerfile.dispatcher\n container_name: flowai-dispatcher\n command: python3 -m app.services.bot_scheduler\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n - postgres\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f bot_scheduler || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 2. 行情总线 (Market Data Bus) ====================\n # 职责: 维护 WebSocket 长连接,将实时行情推送到 Redis\n market-publisher:\n build: ./backend\n container_name: flowai-market-pub\n command: python3 -m app.services.market_data_publisher\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n # 如果需要 API Key (通常 WebSocket 公共频道不需要)\n # - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f market_data_publisher || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 3. 独立风控 (Risk Sidecar) ====================\n # 职责: 独立守护进程,监控账户净值与 Bot 亏损,执行熔断\n risk-monitor:\n build: ./backend\n container_name: flowai-risk-monitor\n command: python3 -m app.services.risk_monitor\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n depends_on:\n - postgres\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f risk_monitor || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 4. 交易执行器 (Celery Workers) ====================\n # 职责: 消费任务队列,执行具体的交易决策与下单\n # 可以通过 --scale trading-worker=N 进行水平扩展\n trading-worker:\n build:\n context: ./backend\n container_name: flowai-trading-worker\n command: celery -A app.celery_app worker --loglevel=info -Q trading,celery --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - USE_DYNAMIC_TOOLS=${USE_DYNAMIC_TOOLS:-true}\n - TOOL_TIMEOUT_TIER1=${TOOL_TIMEOUT_TIER1:-30}\n - TOOL_TIMEOUT_TIER2=${TOOL_TIMEOUT_TIER2:-10}\n - TOOL_TIMEOUT_TIER3=${TOOL_TIMEOUT_TIER3:-5}\n - TOOL_HEALTH_THRESHOLD=${TOOL_HEALTH_THRESHOLD:-0.5}\n depends_on:\n - postgres\n - redis\n - qdrant\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 2G\n\n # ==================== 5. Celery Beat 定时任务调度器 ====================\n # 职责: 执行定时任务(如每日策略复盘、数据爬取等)\n # Phase 3: 每日策略进化复盘任务依赖此服务\n celery-beat:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-beat\n command: celery -A app.celery_app beat --loglevel=info\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n - USE_DYNAMIC_TOOLS=${USE_DYNAMIC_TOOLS:-true}\n - TOOL_TIMEOUT_TIER1=${TOOL_TIMEOUT_TIER1:-30}\n - TOOL_TIMEOUT_TIER2=${TOOL_TIMEOUT_TIER2:-10}\n - TOOL_TIMEOUT_TIER3=${TOOL_TIMEOUT_TIER3:-5}\n - TOOL_HEALTH_THRESHOLD=${TOOL_HEALTH_THRESHOLD:-0.5}\n depends_on:\n - postgres\n - redis\n - qdrant\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f 'celery.*beat' || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '0.25'\n memory: 512M\n\n # ==================== FinRL 服务 ====================\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: unless-stopped\n volumes:\n - /data/finrl/models:/models\n ports:\n - \"8001:8001\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 4G\n\n # ==================== Market Data Microservice ====================\n market-service:\n build:\n context: ./backend/microservices/market\n dockerfile: Dockerfile\n container_name: crypto-ai-market-service\n restart: unless-stopped\n ports:\n - \"8002:8000\"\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n - EXCHANGE_API_SECRET=${EXCHANGE_API_SECRET}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 1G\n\n # ==================== Backend API 服务 ====================\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n ports:\n - \"8000:8000\"\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - FINRL_SERVICE_URL=http://finrl:8001\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n - JWT_SECRET_KEY=${JWT_SECRET_KEY}\n - ENVIRONMENT=development\n - USE_DYNAMIC_TOOLS=${USE_DYNAMIC_TOOLS:-true}\n - TOOL_TIMEOUT_TIER1=${TOOL_TIMEOUT_TIER1:-30}\n - TOOL_TIMEOUT_TIER2=${TOOL_TIMEOUT_TIER2:-10}\n - TOOL_TIMEOUT_TIER3=${TOOL_TIMEOUT_TIER3:-5}\n - TOOL_HEALTH_THRESHOLD=${TOOL_HEALTH_THRESHOLD:-0.5}\n depends_on:\n - postgres\n - redis\n - qdrant\n - finrl\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 2G\n\n # ==================== 新增:Frontend UI 服务 ====================\n frontend:\n # 生产模式构建\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n # 浏览器通过 /api 前缀访问后端,由 Nginx / Next.js 反向代理\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n container_name: crypto-ai-frontend\n restart: unless-stopped\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n NODE_ENV: production\n ports:\n - \"3000:3000\"\n networks:\n - crypto-ai-network\n deploy:\n resources:\n limits:\n cpus: '2.0'\n memory: 6G\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n"}, "2021fb709db442903f2941bdbd2a353a38d4e876": {"t": 1785749255.515867, "n": 9532, "h": "3a8b80e08539bfd1", "c": "services:\n # ==================== Infrastructure Services ====================\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n ports:\n - \"5432:5432\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"pg_isready -U postgres\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n ports:\n - \"6379:6379\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n volumes:\n - /data/qdrant:/qdrant/storage\n ports:\n - \"6333:6333\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"grep -q ':18BD' /proc/net/tcp*\" ]\n interval: 10s\n timeout: 5s\n retries: 10\n start_period: 20s\n\n # ==================== 1. 调度分发器 (Dispatcher) ====================\n # 替代原有的单体 Polling Scheduler\n # 职责: 扫描数据库,将任务分发给 Celery Worker\n # 使用轻量级镜像(无AI依赖)\n bot-dispatcher:\n build:\n context: ./backend\n dockerfile: Dockerfile.dispatcher\n container_name: flowai-dispatcher\n command: python3 -m app.services.bot_scheduler\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n - postgres\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f bot_scheduler || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 2. 行情总线 (Market Data Bus) ====================\n # 职责: 维护 WebSocket 长连接,将实时行情推送到 Redis\n market-publisher:\n build: ./backend\n container_name: flowai-market-pub\n command: python3 -m app.services.market_data_publisher\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n # 如果需要 API Key (通常 WebSocket 公共频道不需要)\n # - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f market_data_publisher || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 3. 独立风控 (Risk Sidecar) ====================\n # 职责: 独立守护进程,监控账户净值与 Bot 亏损,执行熔断\n risk-monitor:\n build: ./backend\n container_name: flowai-risk-monitor\n command: python3 -m app.services.risk_monitor\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n depends_on:\n - postgres\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f risk_monitor || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 4. 交易执行器 (Celery Workers) ====================\n # 职责: 消费任务队列,执行具体的交易决策与下单\n # 可以通过 --scale trading-worker=N 进行水平扩展\n trading-worker:\n build:\n context: ./backend\n container_name: flowai-trading-worker\n command: celery -A app.celery_app worker --loglevel=info -Q trading,celery --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n depends_on:\n - postgres\n - redis\n - qdrant\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 2G\n\n # ==================== 5. Celery Beat 定时任务调度器 ====================\n # 职责: 执行定时任务(如每日策略复盘、数据爬取等)\n # Phase 3: 每日策略进化复盘任务依赖此服务\n celery-beat:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-beat\n command: celery -A app.celery_app beat --loglevel=info\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n depends_on:\n - postgres\n - redis\n - qdrant\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f 'celery.*beat' || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '0.25'\n memory: 512M\n\n # ==================== FinRL 服务 ====================\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: unless-stopped\n volumes:\n - /data/finrl/models:/models\n ports:\n - \"8001:8001\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 4G\n\n # ==================== Market Data Microservice ====================\n market-service:\n build:\n context: ./backend/microservices/market\n dockerfile: Dockerfile\n container_name: crypto-ai-market-service\n restart: unless-stopped\n ports:\n - \"8002:8000\"\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n - EXCHANGE_API_SECRET=${EXCHANGE_API_SECRET}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 1G\n\n # ==================== Backend API 服务 ====================\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n ports:\n - \"8000:8000\"\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - FINRL_SERVICE_URL=http://finrl:8001\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n - JWT_SECRET_KEY=${JWT_SECRET_KEY}\n - ENVIRONMENT=development\n depends_on:\n - postgres\n - redis\n - qdrant\n - finrl\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 2G\n\n # ==================== 新增:Frontend UI 服务 ====================\n frontend:\n # 生产模式构建\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n # 浏览器通过 /api 前缀访问后端,由 Nginx / Next.js 反向代理\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n container_name: crypto-ai-frontend\n restart: unless-stopped\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n NODE_ENV: production\n ports:\n - \"3000:3000\"\n networks:\n - crypto-ai-network\n deploy:\n resources:\n limits:\n cpus: '2.0'\n memory: 6G\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n"}, "cd56be664db4955f7eea51e715bd76c735166ebb": {"t": 1785749256.71273, "n": 8764, "h": "e9e7aa3ab4a9d9d6", "c": "services:\n # ==================== Infrastructure Services ====================\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n ports:\n - \"5432:5432\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n ports:\n - \"6379:6379\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n volumes:\n - /data/qdrant:/qdrant/storage\n ports:\n - \"6333:6333\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"grep -q ':18BD' /proc/net/tcp*\"]\n interval: 10s\n timeout: 5s\n retries: 10\n start_period: 20s\n\n # ==================== 1. 调度分发器 (Dispatcher) ====================\n # 替代原有的单体 Polling Scheduler\n # 职责: 扫描数据库,将任务分发给 Celery Worker\n # 使用轻量级镜像(无AI依赖)\n bot-dispatcher:\n build:\n context: ./backend\n dockerfile: Dockerfile.dispatcher\n container_name: flowai-dispatcher\n command: python3 -m app.services.bot_scheduler\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n - postgres\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [\"CMD-SHELL\", \"pgrep -f bot_scheduler || exit 1\"]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 2. 行情总线 (Market Data Bus) ====================\n # 职责: 维护 WebSocket 长连接,将实时行情推送到 Redis\n market-publisher:\n build: ./backend\n container_name: flowai-market-pub\n command: python3 -m app.services.market_data_publisher\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n # 如果需要 API Key (通常 WebSocket 公共频道不需要)\n # - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [\"CMD-SHELL\", \"pgrep -f market_data_publisher || exit 1\"]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 3. 独立风控 (Risk Sidecar) ====================\n # 职责: 独立守护进程,监控账户净值与 Bot 亏损,执行熔断\n risk-monitor:\n build: ./backend\n container_name: flowai-risk-monitor\n command: python3 -m app.services.risk_monitor\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n depends_on:\n - postgres\n - redis\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [\"CMD-SHELL\", \"pgrep -f risk_monitor || exit 1\"]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '0.50'\n memory: 512M\n\n # ==================== 4. 交易执行器 (Celery Workers) ====================\n # 职责: 消费任务队列,执行具体的交易决策与下单\n # 可以通过 --scale trading-worker=N 进行水平扩展\n trading-worker:\n build: \n context: ./backend\n container_name: flowai-trading-worker\n command: celery -A app.celery_app worker --loglevel=info -Q trading,celery --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n depends_on:\n - postgres\n - redis\n - qdrant\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [\"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\"]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 2G\n\n # ==================== 5. Celery Beat 定时任务调度器 ====================\n # 职责: 执行定时任务(如每日策略复盘、数据爬取等)\n # Phase 3: 每日策略进化复盘任务依赖此服务\n celery-beat:\n build: \n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-beat\n command: celery -A app.celery_app beat --loglevel=info\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n depends_on:\n - postgres\n - redis\n - qdrant\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [\"CMD-SHELL\", \"pgrep -f 'celery.*beat' || exit 1\"]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '0.25'\n memory: 512M\n\n # ==================== FinRL 服务 ====================\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: unless-stopped\n volumes:\n - /data/finrl/models:/models\n ports:\n - \"8001:8001\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 4G\n\n # ==================== Backend API 服务 ====================\n backend:\n build: \n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n ports:\n - \"8000:8000\"\n environment:\n - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/crypto_ai\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - QDRANT_URL=http://qdrant:6333\n - FINRL_SERVICE_URL=http://finrl:8001\n - OPENAI_API_KEY=${OPENAI_API_KEY}\n - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}\n - ENCRYPTION_KEY=${ENCRYPTION_KEY}\n - JWT_SECRET_KEY=${JWT_SECRET_KEY}\n - ENVIRONMENT=development\n depends_on:\n - postgres\n - redis\n - qdrant\n - finrl\n networks:\n - crypto-ai-network\n restart: unless-stopped\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\"]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 2G\n\n # ==================== 新增:Frontend UI 服务 ====================\n frontend:\n # 生产模式构建\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n # 浏览器通过 /api 前缀访问后端,由 Nginx / Next.js 反向代理\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n container_name: crypto-ai-frontend\n restart: unless-stopped\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n NODE_ENV: production\n ports:\n - \"3000:3000\"\n networks:\n - crypto-ai-network\n deploy:\n resources:\n limits:\n cpus: '2.0'\n memory: 6G\n\nnetworks:\n crypto-ai-network:\n driver: bridge"}, "029786d281f62e3140eaaafb154d16a82290cdb4": {"t": 1785749259.2796478, "n": 1326, "h": "b8a8118cf1658330", "c": "version: '3.8'\n\nservices:\n # ==================== 前端开发环境 ====================\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile.dev\n environment:\n - NODE_ENV=development\n volumes:\n - ./frontend:/app\n - /app/node_modules\n - /app/.next\n command: npm run dev\n # 端口映射保持不变 (3000:3000)\n\n # ==================== 后端开发环境 ====================\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile.dev\n environment:\n - LOG_LEVEL=DEBUG\n - ENVIRONMENT=development\n volumes:\n - ./backend:/app\n - /data/freqtrade/user_data:/app/freqtrade/user_data # 保留数据卷到新盘\n - /app/logs\n command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload\n # 端口映射保持不变 (8000:8000)\n\n # ==================== Celery Worker 开发环境 ====================\n celery-worker:\n build:\n context: ./backend\n dockerfile: Dockerfile.dev\n environment:\n - LOG_LEVEL=DEBUG\n - ENVIRONMENT=development\n volumes:\n - ./backend:/app\n - /app/freqtrade/user_data\n command: watchmedo auto-restart --directory=./app --pattern=*.py --recursive -- celery -A app.celery_app:celery_app worker --loglevel=debug\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n"}, "c508b7aa6183c7f7e116f521961e37497f443375": {"t": 1785749260.3679285, "n": 1297, "h": "41847b2194bfd542", "c": "version: '3.8'\n\nservices:\n # ==================== 前端开发环境 ====================\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile.dev\n environment:\n - NODE_ENV=development\n volumes:\n - ./frontend:/app\n - /app/node_modules\n - /app/.next\n command: npm run dev\n # 端口映射保持不变 (3000:3000)\n\n # ==================== 后端开发环境 ====================\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile.dev\n environment:\n - LOG_LEVEL=DEBUG\n - ENVIRONMENT=development\n volumes:\n - ./backend:/app\n - /app/freqtrade/user_data # 保留数据卷\n - /app/logs\n command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload\n # 端口映射保持不变 (8000:8000)\n\n # ==================== Celery Worker 开发环境 ====================\n celery-worker:\n build:\n context: ./backend\n dockerfile: Dockerfile.dev\n environment:\n - LOG_LEVEL=DEBUG\n - ENVIRONMENT=development\n volumes:\n - ./backend:/app\n - /app/freqtrade/user_data\n command: watchmedo auto-restart --directory=./app --pattern=*.py --recursive -- celery -A app.celery_app:celery_app worker --loglevel=debug\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n"}}, "scripts/start-backend-only.sh": {"94cc7095db1259c5f1cb053bdf5c74bb0c4c16c3": {"t": 1785745957.8122332, "n": 1399, "h": "f234f31499751658", "c": "#!/bin/bash\n# 仅启动本地后端(用于单独测试后端)\n\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nPROJECT_ROOT=\"$(cd \"$SCRIPT_DIR/..\" && pwd)\"\n\necho \"==========================================\"\necho \"FlowAI 本地后端启动脚本\"\necho \"==========================================\"\necho \"\"\n\n# 检查 .env 文件\nif [ ! -f \"$PROJECT_ROOT/.env\" ]; then\n echo \"❌ 错误: .env 文件不存在\"\n exit 1\nfi\n\n# 加载环境变量\nsource \"$PROJECT_ROOT/.env\"\n\ncd \"$PROJECT_ROOT/backend\"\n\n# 检查虚拟环境\nif [ ! -d \".venv\" ]; then\n echo \"创建 Python 虚拟环境...\"\n python3 -m venv .venv\nfi\n\n# 激活虚拟环境\nsource .venv/bin/activate\n\n# 检查依赖\nif [ ! -f \".venv/bin/uvicorn\" ]; then\n echo \"安装 Python 依赖...\"\n pip install --upgrade pip\n pip install -r requirements.txt\nfi\n\n# 设置环境变量\nexport DATABASE_URL=\"${DATABASE_URL:-postgresql://postgres:${POSTGRES_PASSWORD}@localhost:5432/crypto_ai}\"\nexport REDIS_URL=\"${REDIS_URL:-redis://:${REDIS_PASSWORD}@localhost:6379/0}\"\nexport QDRANT_URL=\"${QDRANT_URL:-http://localhost:6333}\"\nexport DEEPSEEK_API_KEY=\"${DEEPSEEK_API_KEY}\"\nexport OPENAI_API_KEY=\"${OPENAI_API_KEY}\"\nexport AUTH_SECRET=\"${AUTH_SECRET}\"\nexport ENCRYPTION_KEY=\"${ENCRYPTION_KEY:-ME_hndZpaHq6odQHTgllZkKbnmS80wkcikgmoLaA-Mw}\"\n\necho \"✅ 环境就绪\"\necho \"启动后端服务 (端口 8100)...\"\necho \"访问: http://localhost:8100\"\necho \"健康检查: http://localhost:8100/health\"\necho \"\"\necho \"按 Ctrl+C 停止服务\"\necho \"\"\n\n# 启动后端\nuvicorn app.main:app --reload --host 0.0.0.0 --port 8100\n\n\n\n\n\n\n\n\n"}, "da51efd94b36d6ba34d263f19704b91718b7c46f": {"t": 1785749252.287505, "n": 1399, "h": "f234f31499751658", "c": "#!/bin/bash\n# 仅启动本地后端(用于单独测试后端)\n\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nPROJECT_ROOT=\"$(cd \"$SCRIPT_DIR/..\" && pwd)\"\n\necho \"==========================================\"\necho \"FlowAI 本地后端启动脚本\"\necho \"==========================================\"\necho \"\"\n\n# 检查 .env 文件\nif [ ! -f \"$PROJECT_ROOT/.env\" ]; then\n echo \"❌ 错误: .env 文件不存在\"\n exit 1\nfi\n\n# 加载环境变量\nsource \"$PROJECT_ROOT/.env\"\n\ncd \"$PROJECT_ROOT/backend\"\n\n# 检查虚拟环境\nif [ ! -d \".venv\" ]; then\n echo \"创建 Python 虚拟环境...\"\n python3 -m venv .venv\nfi\n\n# 激活虚拟环境\nsource .venv/bin/activate\n\n# 检查依赖\nif [ ! -f \".venv/bin/uvicorn\" ]; then\n echo \"安装 Python 依赖...\"\n pip install --upgrade pip\n pip install -r requirements.txt\nfi\n\n# 设置环境变量\nexport DATABASE_URL=\"${DATABASE_URL:-postgresql://postgres:${POSTGRES_PASSWORD}@localhost:5432/crypto_ai}\"\nexport REDIS_URL=\"${REDIS_URL:-redis://:${REDIS_PASSWORD}@localhost:6379/0}\"\nexport QDRANT_URL=\"${QDRANT_URL:-http://localhost:6333}\"\nexport DEEPSEEK_API_KEY=\"${DEEPSEEK_API_KEY}\"\nexport OPENAI_API_KEY=\"${OPENAI_API_KEY}\"\nexport AUTH_SECRET=\"${AUTH_SECRET}\"\nexport ENCRYPTION_KEY=\"${ENCRYPTION_KEY:-ME_hndZpaHq6odQHTgllZkKbnmS80wkcikgmoLaA-Mw}\"\n\necho \"✅ 环境就绪\"\necho \"启动后端服务 (端口 8100)...\"\necho \"访问: http://localhost:8100\"\necho \"健康检查: http://localhost:8100/health\"\necho \"\"\necho \"按 Ctrl+C 停止服务\"\necho \"\"\n\n# 启动后端\nuvicorn app.main:app --reload --host 0.0.0.0 --port 8100\n\n\n\n\n\n\n\n\n"}, "35d7d78548bf60e7243d265f708a65ae858af96a": {"t": 1785749253.3661826, "n": 1395, "h": "90f47973db702f14", "c": "#!/bin/bash\n# 仅启动本地后端(用于单独测试后端)\n\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nPROJECT_ROOT=\"$(cd \"$SCRIPT_DIR/..\" && pwd)\"\n\necho \"==========================================\"\necho \"FlowAI 本地后端启动脚本\"\necho \"==========================================\"\necho \"\"\n\n# 检查 .env 文件\nif [ ! -f \"$PROJECT_ROOT/.env\" ]; then\n echo \"❌ 错误: .env 文件不存在\"\n exit 1\nfi\n\n# 加载环境变量\nsource \"$PROJECT_ROOT/.env\"\n\ncd \"$PROJECT_ROOT/backend\"\n\n# 检查虚拟环境\nif [ ! -d \".venv\" ]; then\n echo \"创建 Python 虚拟环境...\"\n python3 -m venv .venv\nfi\n\n# 激活虚拟环境\nsource .venv/bin/activate\n\n# 检查依赖\nif [ ! -f \".venv/bin/uvicorn\" ]; then\n echo \"安装 Python 依赖...\"\n pip install --upgrade pip\n pip install -r requirements.txt\nfi\n\n# 设置环境变量\nexport DATABASE_URL=\"${DATABASE_URL:-postgresql://postgres:${POSTGRES_PASSWORD}@localhost:5432/crypto_ai}\"\nexport REDIS_URL=\"${REDIS_URL:-redis://:${REDIS_PASSWORD}@localhost:6379/0}\"\nexport QDRANT_URL=\"${QDRANT_URL:-http://localhost:6333}\"\nexport DEEPSEEK_API_KEY=\"${DEEPSEEK_API_KEY}\"\nexport OPENAI_API_KEY=\"${OPENAI_API_KEY}\"\nexport AUTH_SECRET=\"${AUTH_SECRET}\"\nexport ENCRYPTION_KEY=\"${ENCRYPTION_KEY:-ME_hndZpaHq6odQHTgllZkKbnmS80wkcikgmoLaA-Mw}\"\n\necho \"✅ 环境就绪\"\necho \"启动后端服务 (端口 8100)...\"\necho \"访问: http://localhost:8100\"\necho \"健康检查: http://localhost:8100/health\"\necho \"\"\necho \"按 Ctrl+C 停止服务\"\necho \"\"\n\n# 启动后端\nuvicorn app.main:app --reload --host 0.0.0.0 --port 8100\n\n\n\n\n"}, "5d1282187360c76c2a765713118fd028a1eefab3": {"t": 1785749254.5384083, "n": 1392, "h": "fbe04a79ead99c2b", "c": "#!/bin/bash\n# 仅启动本地后端(用于单独测试后端)\n\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nPROJECT_ROOT=\"$(cd \"$SCRIPT_DIR/..\" && pwd)\"\n\necho \"==========================================\"\necho \"FlowAI 本地后端启动脚本\"\necho \"==========================================\"\necho \"\"\n\n# 检查 .env 文件\nif [ ! -f \"$PROJECT_ROOT/.env\" ]; then\n echo \"❌ 错误: .env 文件不存在\"\n exit 1\nfi\n\n# 加载环境变量\nsource \"$PROJECT_ROOT/.env\"\n\ncd \"$PROJECT_ROOT/backend\"\n\n# 检查虚拟环境\nif [ ! -d \".venv\" ]; then\n echo \"创建 Python 虚拟环境...\"\n python3 -m venv .venv\nfi\n\n# 激活虚拟环境\nsource .venv/bin/activate\n\n# 检查依赖\nif [ ! -f \".venv/bin/uvicorn\" ]; then\n echo \"安装 Python 依赖...\"\n pip install --upgrade pip\n pip install -r requirements.txt\nfi\n\n# 设置环境变量\nexport DATABASE_URL=\"${DATABASE_URL:-postgresql://postgres:${POSTGRES_PASSWORD}@localhost:5432/crypto_ai}\"\nexport REDIS_URL=\"${REDIS_URL:-redis://:${REDIS_PASSWORD}@localhost:6379/0}\"\nexport QDRANT_URL=\"${QDRANT_URL:-http://localhost:6333}\"\nexport DEEPSEEK_API_KEY=\"${DEEPSEEK_API_KEY}\"\nexport OPENAI_API_KEY=\"${OPENAI_API_KEY}\"\nexport AUTH_SECRET=\"${AUTH_SECRET}\"\nexport ENCRYPTION_KEY=\"${ENCRYPTION_KEY:-ME_hndZpaHq6odQHTgllZkKbnmS80wkcikgmoLaA-Mw}\"\n\necho \"✅ 环境就绪\"\necho \"启动后端服务 (端口 8100)...\"\necho \"访问: http://localhost:8100\"\necho \"健康检查: http://localhost:8100/health\"\necho \"\"\necho \"按 Ctrl+C 停止服务\"\necho \"\"\n\n# 启动后端\nuvicorn app.main:app --reload --host 0.0.0.0 --port 8100\n\n"}}, "docker-compose.prod.yml": {"94cc7095db1259c5f1cb053bdf5c74bb0c4c16c3": {"t": 1785747414.3483422, "n": 15502, "h": "fa5474c8c87366c2", "c": "services:\n # PostgreSQL数据库\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n ports:\n - \"5432:5432\"\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"pg_isready -U postgres\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Redis缓存\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n ports:\n - \"6379:6379\"\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Qdrant向量数据库\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n ports:\n - \"6333:6333\"\n volumes:\n - /data/qdrant:/qdrant/storage\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"grep -q ':18BD' /proc/net/tcp*\" ]\n interval: 10s\n timeout: 5s\n retries: 10\n start_period: 20s\n\n # 后端API\n backend:\n build:\n context: .\n dockerfile: backend/Dockerfile\n image: flowai-backend-v3:latest\n\n container_name: crypto-ai-backend\n restart: always\n command: [ \"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\", \"--workers\", \"1\" ]\n environment:\n # 数据库配置\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n FINRL_SERVICE_URL: http://finrl:8001\n MARKET_SERVICE_URL: http://market-service:8000\n\n # API密钥\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n OPENAI_API_BASE: ${OPENAI_API_BASE}\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n OPENAI_MODEL: ${OPENAI_MODEL:-gemini-2.5-flash-thinking}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DEEPSEEK_BASE_URL: https://api.aifast.top/v1\n DEEPSEEK_MODEL: ${DEEPSEEK_MODEL:-gemini-2.5-flash-thinking}\n API_KEY_ENCRYPTION_SECRET: ${API_KEY_ENCRYPTION_SECRET}\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n NOWPAYMENTS_API_KEY: ${NOWPAYMENTS_API_KEY}\n NOWPAYMENTS_IPN_SECRET: ${NOWPAYMENTS_IPN_SECRET}\n\n # JWT配置\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n JWT_ALGORITHM: HS256\n JWT_EXPIRE_MINUTES: 10080\n\n # 应用配置\n ENVIRONMENT: production\n LOG_LEVEL: info\n DISABLE_JINSE: \"1\"\n CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}\n API_BASE_URL: ${BACKEND_URL:-https://cfish.cc/api}\n FRONTEND_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n\n # Search Config\n WEB_SEARCH_PROVIDER: searxng\n SEARXNG_URL: http://searxng:8080\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n networks:\n - crypto-ai-network\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n finrl:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 1536M\n\n # FinRL 服务\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: always\n volumes:\n - /data/finrl/models:/models\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n\n # ==================== Market Data Microservice ====================\n market-service:\n build:\n context: ./backend/microservices/market\n dockerfile: Dockerfile\n container_name: crypto-ai-market-service\n restart: always\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n - EXCHANGE_API_SECRET=${EXCHANGE_API_SECRET}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 1G\n\n # New Frontend UI Service\n bot-dispatcher:\n build:\n context: .\n dockerfile: backend/Dockerfile\n image: flowai-backend-v3:latest\n\n container_name: flowai-dispatcher\n restart: always\n command: python3 -m app.services.bot_scheduler\n environment:\n ENVIRONMENT: production\n LOG_LEVEL: info\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DEEPSEEK_BASE_URL: https://api.aifast.top/v1\n WEB_SEARCH_PROVIDER: searxng\n SEARXNG_URL: http://searxng:8080\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.bot_scheduler' in open('/proc/1/cmdline','rb').read() else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 行情总线 (Market Publisher)\n market-publisher:\n build:\n context: .\n dockerfile: backend/Dockerfile\n image: flowai-backend-v3:latest\n\n container_name: flowai-market-pub\n restart: always\n command: python3 -m app.services.market_data_publisher\n environment:\n ENVIRONMENT: production\n LOG_LEVEL: info\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n depends_on:\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.market_data_publisher' in open('/proc/1/cmdline','rb').read() else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 风控守护 (Risk Monitor)\n risk-monitor:\n build:\n context: .\n dockerfile: backend/Dockerfile\n image: flowai-backend-v3:latest\n\n container_name: flowai-risk-monitor\n restart: always\n command: python3 -m app.services.risk_monitor\n environment:\n ENVIRONMENT: production\n LOG_LEVEL: info\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.risk_monitor' in open('/proc/1/cmdline','rb').read() else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 交易执行器 (Celery Worker)\n trading-worker:\n build:\n context: .\n dockerfile: backend/Dockerfile\n image: flowai-backend-v3:latest\n\n container_name: flowai-trading-worker\n restart: always\n command: celery -A app.celery_app worker --loglevel=info -Q trading --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n ENVIRONMENT: production\n LOG_LEVEL: info\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n WEB_SEARCH_PROVIDER: searxng\n SEARXNG_URL: http://searxng:8080\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DEEPSEEK_BASE_URL: https://api.aifast.top/v1\n DISABLE_JINSE: \"1\"\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '0.5'\n memory: 512M\n\n celery-worker:\n build:\n context: .\n dockerfile: backend/Dockerfile\n image: flowai-backend-v3:latest\n\n container_name: flowai-celery-worker\n restart: always\n command: celery -A app.celery_app worker --loglevel=info -Q celery --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n ENVIRONMENT: production\n LOG_LEVEL: info\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n WEB_SEARCH_PROVIDER: searxng\n SEARXNG_URL: http://searxng:8080\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DISABLE_JINSE: \"1\"\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n deploy:\n resources:\n limits:\n cpus: '0.8'\n memory: 1G\n\n # Celery Beat 定时任务调度器\n celery-beat:\n build:\n context: .\n dockerfile: backend/Dockerfile\n image: flowai-backend-v3:latest\n\n container_name: flowai-celery-beat\n restart: always\n command: celery -A app.celery_app beat --loglevel=info\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n ENVIRONMENT: production\n LOG_LEVEL: info\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n WEB_SEARCH_PROVIDER: searxng\n SEARXNG_URL: http://searxng:8080\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DISABLE_JINSE: \"1\"\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; d=open('/proc/1/cmdline','rb').read(); sys.exit(0 if (b'celery' in d and b'beat' in d) else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n # 前端应用\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://cfish.cc/api}\n NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n AUTH_URL: ${AUTH_URL:-https://cfish.cc}\n NEXTAUTH_URL: ${NEXTAUTH_URL:-https://cfish.cc}\n container_name: crypto-ai-frontend\n restart: always\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n AUTH_URL: ${AUTH_URL:-https://cfish.cc}\n NEXTAUTH_URL: ${NEXTAUTH_URL:-https://cfish.cc}\n AUTH_TRUST_HOST: \"true\"\n NODE_ENV: production\n networks:\n - crypto-ai-network\n depends_on:\n backend:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD-SHELL\", \"node -e \\\"require('net').connect(3000,'127.0.0.1',()=>process.exit(0)).on('error',()=>process.exit(1))\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 10\n start_period: 120s\n\n # Nginx反向代理\n nginx:\n image: nginx:alpine\n container_name: crypto-ai-nginx\n restart: always\n volumes:\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro\n - ./nginx/gzip.conf:/etc/nginx/gzip.conf:ro\n - ./nginx/conf.d:/etc/nginx/conf.d:ro\n - ./nginx/ssl:/etc/nginx/ssl:ro\n - ./certbot/www:/var/www/certbot:ro\n - /data/nginx/logs:/var/log/nginx\n ports:\n - \"80:80\"\n - \"443:443\"\n networks:\n - crypto-ai-network\n depends_on:\n frontend:\n condition: service_healthy\n backend:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD\", \"nginx\", \"-t\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # Search Engine\n searxng:\n image: searxng/searxng:latest\n container_name: searxng\n restart: always\n networks:\n - crypto-ai-network\n volumes:\n - ./searxng:/etc/searxng:rw\n environment:\n - SEARXNG_SETTINGS_PATH=/etc/searxng/settings.yml\n ports:\n - \"8080:8080\"\n cap_drop:\n - ALL\n cap_add:\n - CHOWN\n - SETGID\n - SETUID\n logging:\n driver: \"json-file\"\n options:\n max-size: \"10m\"\n max-file: \"3\"\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n"}, "e2a9d134ea09324bc8ad87e826e5c83e34830734": {"t": 1785749253.4792337, "n": 12834, "h": "0bc4450099bbba77", "c": "services:\n # PostgreSQL数据库\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n ports:\n - \"5432:5432\"\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"pg_isready -U postgres\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Redis缓存\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n ports:\n - \"6379:6379\"\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Qdrant向量数据库\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n ports:\n - \"6333:6333\"\n volumes:\n - /data/qdrant:/qdrant/storage\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"grep -q ':18BD' /proc/net/tcp*\" ]\n interval: 10s\n timeout: 5s\n retries: 10\n start_period: 20s\n\n # 后端API\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n restart: always\n environment:\n # 数据库配置\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n FINRL_SERVICE_URL: http://finrl:8001\n MARKET_SERVICE_URL: http://market-service:8000\n\n # API密钥\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n OPENAI_API_BASE: ${OPENAI_API_BASE}\n<<<<<<< HEAD\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n=======\n>>>>>>> 73439532426f5539ba2fb68eb91e077cfb542b08\n OPENAI_MODEL: ${OPENAI_MODEL:-gemini-2.5-flash-thinking}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DEEPSEEK_MODEL: ${DEEPSEEK_MODEL:-gemini-2.5-flash-thinking}\n API_KEY_ENCRYPTION_SECRET: ${API_KEY_ENCRYPTION_SECRET}\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n NOWPAYMENTS_API_KEY: ${NOWPAYMENTS_API_KEY}\n NOWPAYMENTS_IPN_SECRET: ${NOWPAYMENTS_IPN_SECRET}\n\n # JWT配置\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n JWT_ALGORITHM: HS256\n JWT_EXPIRE_MINUTES: 10080\n\n # 应用配置\n ENVIRONMENT: production\n LOG_LEVEL: info\n DISABLE_JINSE: \"1\"\n CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}\n API_BASE_URL: ${BACKEND_URL:-https://cfish.cc/api}\n FRONTEND_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n networks:\n - crypto-ai-network\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n finrl:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # FinRL 服务\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: always\n volumes:\n - /data/finrl/models:/models\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n\n # ==================== Market Data Microservice ====================\n market-service:\n build:\n context: ./backend/microservices/market\n dockerfile: Dockerfile\n container_name: crypto-ai-market-service\n restart: always\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n - EXCHANGE_API_SECRET=${EXCHANGE_API_SECRET}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 1G\n\n # New Frontend UI Service\n bot-dispatcher:\n build:\n context: ./backend\n dockerfile: Dockerfile.dispatcher\n container_name: flowai-dispatcher\n restart: always\n command: python3 -m app.services.bot_scheduler\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f bot_scheduler || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 行情总线 (Market Publisher)\n market-publisher:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-market-pub\n restart: always\n command: python3 -m app.services.market_data_publisher\n environment:\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.market_data_publisher' in open('/proc/1/cmdline','rb').read() else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 风控守护 (Risk Monitor)\n risk-monitor:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-risk-monitor\n restart: always\n command: python3 -m app.services.risk_monitor\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.risk_monitor' in open('/proc/1/cmdline','rb').read() else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 交易执行器 (Celery Worker)\n trading-worker:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-trading-worker\n restart: always\n command: celery -A app.celery_app worker --loglevel=info -Q trading --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DISABLE_JINSE: \"1\"\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n celery-worker:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-worker\n restart: always\n command: celery -A app.celery_app worker --loglevel=info -Q celery --concurrency=2\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DISABLE_JINSE: \"1\"\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n # Celery Beat 定时任务调度器\n celery-beat:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-beat\n restart: always\n command: celery -A app.celery_app beat --loglevel=info\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DISABLE_JINSE: \"1\"\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; d=open('/proc/1/cmdline','rb').read(); sys.exit(0 if (b'celery' in d and b'beat' in d) else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n # 前端应用\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://cfish.cc/api}\n NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n AUTH_URL: ${AUTH_URL:-https://cfish.cc}\n NEXTAUTH_URL: ${NEXTAUTH_URL:-https://cfish.cc}\n container_name: crypto-ai-frontend\n restart: always\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n AUTH_URL: ${AUTH_URL:-https://cfish.cc}\n NEXTAUTH_URL: ${NEXTAUTH_URL:-https://cfish.cc}\n AUTH_TRUST_HOST: \"true\"\n NODE_ENV: production\n networks:\n - crypto-ai-network\n depends_on:\n backend:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD-SHELL\", \"node -e \\\"require('net').connect(3000,'127.0.0.1',()=>process.exit(0)).on('error',()=>process.exit(1))\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 10\n start_period: 120s\n\n # Nginx反向代理\n nginx:\n image: nginx:alpine\n container_name: crypto-ai-nginx\n restart: always\n volumes:\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro\n - ./nginx/gzip.conf:/etc/nginx/gzip.conf:ro\n - ./nginx/conf.d:/etc/nginx/conf.d:ro\n - ./nginx/ssl:/etc/nginx/ssl:ro\n - ./certbot/www:/var/www/certbot:ro\n - /data/nginx/logs:/var/log/nginx\n ports:\n - \"80:80\"\n - \"443:443\"\n networks:\n - crypto-ai-network\n depends_on:\n frontend:\n condition: service_healthy\n backend:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD\", \"nginx\", \"-t\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n"}, "7fe52b597687befcd02e3cb00104c28bdb689766": {"t": 1785749254.5796752, "n": 12764, "h": "83cd3cafef5db985", "c": "services:\n # PostgreSQL数据库\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n ports:\n - \"5432:5432\"\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"pg_isready -U postgres\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Redis缓存\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n ports:\n - \"6379:6379\"\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Qdrant向量数据库\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n ports:\n - \"6333:6333\"\n volumes:\n - /data/qdrant:/qdrant/storage\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"grep -q ':18BD' /proc/net/tcp*\" ]\n interval: 10s\n timeout: 5s\n retries: 10\n start_period: 20s\n\n # 后端API\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n restart: always\n environment:\n # 数据库配置\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n FINRL_SERVICE_URL: http://finrl:8001\n MARKET_SERVICE_URL: http://market-service:8000\n\n # API密钥\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n OPENAI_API_BASE: ${OPENAI_API_BASE}\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n OPENAI_MODEL: ${OPENAI_MODEL:-gemini-2.5-flash-thinking}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DEEPSEEK_MODEL: ${DEEPSEEK_MODEL:-gemini-2.5-flash-thinking}\n API_KEY_ENCRYPTION_SECRET: ${API_KEY_ENCRYPTION_SECRET}\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n NOWPAYMENTS_API_KEY: ${NOWPAYMENTS_API_KEY}\n NOWPAYMENTS_IPN_SECRET: ${NOWPAYMENTS_IPN_SECRET}\n\n # JWT配置\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n JWT_ALGORITHM: HS256\n JWT_EXPIRE_MINUTES: 10080\n\n # 应用配置\n ENVIRONMENT: production\n LOG_LEVEL: info\n DISABLE_JINSE: \"1\"\n CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}\n API_BASE_URL: ${BACKEND_URL:-https://cfish.cc/api}\n FRONTEND_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n networks:\n - crypto-ai-network\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n finrl:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # FinRL 服务\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: always\n volumes:\n - /data/finrl/models:/models\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n\n # ==================== Market Data Microservice ====================\n market-service:\n build:\n context: ./backend/microservices/market\n dockerfile: Dockerfile\n container_name: crypto-ai-market-service\n restart: always\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n - EXCHANGE_API_SECRET=${EXCHANGE_API_SECRET}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 1G\n\n # New Frontend UI Service\n bot-dispatcher:\n build:\n context: ./backend\n dockerfile: Dockerfile.dispatcher\n container_name: flowai-dispatcher\n restart: always\n command: python3 -m app.services.bot_scheduler\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f bot_scheduler || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 行情总线 (Market Publisher)\n market-publisher:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-market-pub\n restart: always\n command: python3 -m app.services.market_data_publisher\n environment:\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.market_data_publisher' in open('/proc/1/cmdline','rb').read() else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 风控守护 (Risk Monitor)\n risk-monitor:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-risk-monitor\n restart: always\n command: python3 -m app.services.risk_monitor\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.risk_monitor' in open('/proc/1/cmdline','rb').read() else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 交易执行器 (Celery Worker)\n trading-worker:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-trading-worker\n restart: always\n command: celery -A app.celery_app worker --loglevel=info -Q trading --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DISABLE_JINSE: \"1\"\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n celery-worker:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-worker\n restart: always\n command: celery -A app.celery_app worker --loglevel=info -Q celery --concurrency=2\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DISABLE_JINSE: \"1\"\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n # Celery Beat 定时任务调度器\n celery-beat:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-beat\n restart: always\n command: celery -A app.celery_app beat --loglevel=info\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n EMBEDDING_MODEL: ${EMBEDDING_MODEL:-text-embedding-ada-002}\n EMBEDDING_API_KEY: ${EMBEDDING_API_KEY}\n EMBEDDING_API_BASE: ${EMBEDDING_API_BASE}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DISABLE_JINSE: \"1\"\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; d=open('/proc/1/cmdline','rb').read(); sys.exit(0 if (b'celery' in d and b'beat' in d) else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n # 前端应用\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://cfish.cc/api}\n NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n AUTH_URL: ${AUTH_URL:-https://cfish.cc}\n NEXTAUTH_URL: ${NEXTAUTH_URL:-https://cfish.cc}\n container_name: crypto-ai-frontend\n restart: always\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n AUTH_URL: ${AUTH_URL:-https://cfish.cc}\n NEXTAUTH_URL: ${NEXTAUTH_URL:-https://cfish.cc}\n AUTH_TRUST_HOST: \"true\"\n NODE_ENV: production\n networks:\n - crypto-ai-network\n depends_on:\n backend:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD-SHELL\", \"node -e \\\"require('net').connect(3000,'127.0.0.1',()=>process.exit(0)).on('error',()=>process.exit(1))\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 10\n start_period: 120s\n\n # Nginx反向代理\n nginx:\n image: nginx:alpine\n container_name: crypto-ai-nginx\n restart: always\n volumes:\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro\n - ./nginx/gzip.conf:/etc/nginx/gzip.conf:ro\n - ./nginx/conf.d:/etc/nginx/conf.d:ro\n - ./nginx/ssl:/etc/nginx/ssl:ro\n - ./certbot/www:/var/www/certbot:ro\n - /data/nginx/logs:/var/log/nginx\n ports:\n - \"80:80\"\n - \"443:443\"\n networks:\n - crypto-ai-network\n depends_on:\n frontend:\n condition: service_healthy\n backend:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD\", \"nginx\", \"-t\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n"}, "2021fb709db442903f2941bdbd2a353a38d4e876": {"t": 1785749255.6641982, "n": 10944, "h": "e08cfc68b36c1847", "c": "services:\n # PostgreSQL数据库\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n ports:\n - \"5432:5432\"\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"pg_isready -U postgres\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Redis缓存\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n ports:\n - \"6379:6379\"\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\" ]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Qdrant向量数据库\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n ports:\n - \"6333:6333\"\n volumes:\n - /data/qdrant:/qdrant/storage\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"grep -q ':18BD' /proc/net/tcp*\" ]\n interval: 10s\n timeout: 5s\n retries: 10\n start_period: 20s\n\n # 后端API\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n restart: always\n environment:\n # 数据库配置\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n FINRL_SERVICE_URL: http://finrl:8001\n MARKET_SERVICE_URL: http://market-service:8000\n\n # API密钥\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n OPENAI_API_BASE: ${OPENAI_API_BASE}\n OPENAI_MODEL: ${OPENAI_MODEL:-gemini-2.5-flash-thinking}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DEEPSEEK_MODEL: ${DEEPSEEK_MODEL:-gemini-2.5-flash-thinking}\n API_KEY_ENCRYPTION_SECRET: ${API_KEY_ENCRYPTION_SECRET}\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n NOWPAYMENTS_API_KEY: ${NOWPAYMENTS_API_KEY}\n NOWPAYMENTS_IPN_SECRET: ${NOWPAYMENTS_IPN_SECRET}\n\n # JWT配置\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n JWT_ALGORITHM: HS256\n JWT_EXPIRE_MINUTES: 10080\n\n # 应用配置\n ENVIRONMENT: production\n LOG_LEVEL: info\n CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}\n API_BASE_URL: ${BACKEND_URL:-https://cfish.cc/api}\n FRONTEND_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n networks:\n - crypto-ai-network\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n finrl:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # FinRL 服务\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: always\n volumes:\n - /data/finrl/models:/models\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n\n # ==================== Market Data Microservice ====================\n market-service:\n build:\n context: ./backend/microservices/market\n dockerfile: Dockerfile\n container_name: crypto-ai-market-service\n restart: always\n environment:\n - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0\n - EXCHANGE_API_KEY=${EXCHANGE_API_KEY}\n - EXCHANGE_API_SECRET=${EXCHANGE_API_SECRET}\n depends_on:\n - redis\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n deploy:\n resources:\n limits:\n cpus: '1.0'\n memory: 1G\n\n # New Frontend UI Service\n bot-dispatcher:\n build:\n context: ./backend\n dockerfile: Dockerfile.dispatcher\n container_name: flowai-dispatcher\n restart: always\n command: python3 -m app.services.bot_scheduler\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"pgrep -f bot_scheduler || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 行情总线 (Market Publisher)\n market-publisher:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-market-pub\n restart: always\n command: python3 -m app.services.market_data_publisher\n environment:\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.market_data_publisher' in open('/proc/1/cmdline','rb').read() else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 风控守护 (Risk Monitor)\n risk-monitor:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-risk-monitor\n restart: always\n command: python3 -m app.services.risk_monitor\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.risk_monitor' in open('/proc/1/cmdline','rb').read() else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 交易执行器 (Celery Worker)\n trading-worker:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-trading-worker\n restart: always\n command: celery -A app.celery_app worker --loglevel=info -Q trading,celery --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n # Celery Beat 定时任务调度器\n celery-beat:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-beat\n restart: always\n command: celery -A app.celery_app beat --loglevel=info\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [ \"CMD-SHELL\", \"python -c \\\"import sys; d=open('/proc/1/cmdline','rb').read(); sys.exit(0 if (b'celery' in d and b'beat' in d) else 1)\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n # 前端应用\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://cfish.cc/api}\n NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n AUTH_URL: ${AUTH_URL:-https://cfish.cc}\n NEXTAUTH_URL: ${NEXTAUTH_URL:-https://cfish.cc}\n container_name: crypto-ai-frontend\n restart: always\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n AUTH_URL: ${AUTH_URL:-https://cfish.cc}\n NEXTAUTH_URL: ${NEXTAUTH_URL:-https://cfish.cc}\n AUTH_TRUST_HOST: \"true\"\n NODE_ENV: production\n networks:\n - crypto-ai-network\n depends_on:\n backend:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD-SHELL\", \"node -e \\\"require('net').connect(3000,'127.0.0.1',()=>process.exit(0)).on('error',()=>process.exit(1))\\\"\" ]\n interval: 30s\n timeout: 10s\n retries: 10\n start_period: 120s\n\n # Nginx反向代理\n nginx:\n image: nginx:alpine\n container_name: crypto-ai-nginx\n restart: always\n volumes:\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro\n - ./nginx/gzip.conf:/etc/nginx/gzip.conf:ro\n - ./nginx/conf.d:/etc/nginx/conf.d:ro\n - ./nginx/ssl:/etc/nginx/ssl:ro\n - ./certbot/www:/var/www/certbot:ro\n - /data/nginx/logs:/var/log/nginx\n ports:\n - \"80:80\"\n - \"443:443\"\n networks:\n - crypto-ai-network\n depends_on:\n frontend:\n condition: service_healthy\n backend:\n condition: service_healthy\n healthcheck:\n test: [ \"CMD\", \"nginx\", \"-t\" ]\n interval: 30s\n timeout: 10s\n retries: 3\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n"}, "cd56be664db4955f7eea51e715bd76c735166ebb": {"t": 1785749256.9247131, "n": 10170, "h": "9899528a93f90f72", "c": "services:\n # PostgreSQL数据库\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n ports:\n - \"5432:5432\"\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Redis缓存\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n ports:\n - \"6379:6379\"\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Qdrant向量数据库\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n ports:\n - \"6333:6333\"\n volumes:\n - /data/qdrant:/qdrant/storage\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"grep -q ':18BD' /proc/net/tcp*\"]\n interval: 10s\n timeout: 5s\n retries: 10\n start_period: 20s\n\n # 后端API\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n restart: always\n environment:\n # 数据库配置\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n FINRL_SERVICE_URL: http://finrl:8001\n \n # API密钥\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n OPENAI_API_BASE: ${OPENAI_API_BASE}\n OPENAI_MODEL: ${OPENAI_MODEL:-gemini-2.5-flash-thinking}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n DEEPSEEK_MODEL: ${DEEPSEEK_MODEL:-gemini-2.5-flash-thinking}\n API_KEY_ENCRYPTION_SECRET: ${API_KEY_ENCRYPTION_SECRET}\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n NOWPAYMENTS_API_KEY: ${NOWPAYMENTS_API_KEY}\n NOWPAYMENTS_IPN_SECRET: ${NOWPAYMENTS_IPN_SECRET}\n \n # JWT配置\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n JWT_ALGORITHM: HS256\n JWT_EXPIRE_MINUTES: 10080\n \n # 应用配置\n ENVIRONMENT: production\n LOG_LEVEL: info\n CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}\n API_BASE_URL: ${BACKEND_URL:-https://cfish.cc/api}\n FRONTEND_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n networks:\n - crypto-ai-network\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n finrl:\n condition: service_healthy\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # FinRL 服务\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: always\n volumes:\n - /data/finrl/models:/models\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n\n # 调度分发器 (Dispatcher)\n bot-dispatcher:\n build:\n context: ./backend\n dockerfile: Dockerfile.dispatcher\n container_name: flowai-dispatcher\n restart: always\n command: python3 -m app.services.bot_scheduler\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"pgrep -f bot_scheduler || exit 1\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 行情总线 (Market Publisher)\n market-publisher:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-market-pub\n restart: always\n command: python3 -m app.services.market_data_publisher\n environment:\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.market_data_publisher' in open('/proc/1/cmdline','rb').read() else 1)\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 风控守护 (Risk Monitor)\n risk-monitor:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-risk-monitor\n restart: always\n command: python3 -m app.services.risk_monitor\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.risk_monitor' in open('/proc/1/cmdline','rb').read() else 1)\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 交易执行器 (Celery Worker)\n trading-worker:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-trading-worker\n restart: always\n command: celery -A app.celery_app worker --loglevel=info -Q trading,celery --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\"]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n # Celery Beat 定时任务调度器\n celery-beat:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-beat\n restart: always\n command: celery -A app.celery_app beat --loglevel=info\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"python -c \\\"import sys; d=open('/proc/1/cmdline','rb').read(); sys.exit(0 if (b'celery' in d and b'beat' in d) else 1)\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n # 前端应用\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://cfish.cc/api}\n NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n AUTH_URL: ${AUTH_URL:-https://cfish.cc}\n NEXTAUTH_URL: ${NEXTAUTH_URL:-https://cfish.cc}\n container_name: crypto-ai-frontend\n restart: always\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n AUTH_URL: ${AUTH_URL:-https://cfish.cc}\n NEXTAUTH_URL: ${NEXTAUTH_URL:-https://cfish.cc}\n AUTH_TRUST_HOST: \"true\"\n NODE_ENV: production\n networks:\n - crypto-ai-network\n depends_on:\n backend:\n condition: service_healthy\n healthcheck:\n test: [\"CMD-SHELL\", \"node -e \\\"require('net').connect(3000,'127.0.0.1',()=>process.exit(0)).on('error',()=>process.exit(1))\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 10\n start_period: 120s\n\n # Nginx反向代理\n nginx:\n image: nginx:alpine\n container_name: crypto-ai-nginx\n restart: always\n volumes:\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro\n - ./nginx/gzip.conf:/etc/nginx/gzip.conf:ro\n - ./nginx/conf.d:/etc/nginx/conf.d:ro\n - ./nginx/ssl:/etc/nginx/ssl:ro\n - ./certbot/www:/var/www/certbot:ro\n - /data/nginx/logs:/var/log/nginx\n ports:\n - \"80:80\"\n - \"443:443\"\n networks:\n - crypto-ai-network\n depends_on:\n frontend:\n condition: service_healthy\n backend:\n condition: service_healthy\n healthcheck:\n test: [\"CMD\", \"nginx\", \"-t\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n\n"}, "a1c9218f087fbee8999c559974da3f1ed3078c5a": {"t": 1785749258.0275135, "n": 9443, "h": "a3f8854043577e8b", "c": "version: '3.8'\n\nservices:\n # PostgreSQL数据库\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Redis缓存\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Qdrant向量数据库\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n volumes:\n - /data/qdrant:/qdrant/storage\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"grep -q ':18BD' /proc/net/tcp*\"]\n interval: 10s\n timeout: 5s\n retries: 10\n start_period: 20s\n\n # 后端API\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n restart: always\n environment:\n # 数据库配置\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n FINRL_SERVICE_URL: http://finrl:8001\n \n # API密钥\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n API_KEY_ENCRYPTION_SECRET: ${API_KEY_ENCRYPTION_SECRET}\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n NOWPAYMENTS_API_KEY: ${NOWPAYMENTS_API_KEY}\n NOWPAYMENTS_IPN_SECRET: ${NOWPAYMENTS_IPN_SECRET}\n \n # JWT配置\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n JWT_ALGORITHM: HS256\n JWT_EXPIRE_MINUTES: 10080\n \n # 应用配置\n ENVIRONMENT: production\n LOG_LEVEL: info\n CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}\n API_BASE_URL: ${BACKEND_URL:-https://cfish.cc/api}\n FRONTEND_URL: ${NEXT_PUBLIC_APP_URL:-https://cfish.cc}\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n networks:\n - crypto-ai-network\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n finrl:\n condition: service_healthy\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # FinRL 服务\n finrl:\n build: ./finrl_service\n container_name: crypto-ai-finrl\n restart: always\n volumes:\n - /data/finrl/models:/models\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"python -c \\\"import urllib.request; urllib.request.urlopen('http://localhost:8001/health')\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 20s\n\n # 调度分发器 (Dispatcher)\n bot-dispatcher:\n build:\n context: ./backend\n dockerfile: Dockerfile.dispatcher\n container_name: flowai-dispatcher\n restart: always\n command: python3 -m app.services.bot_scheduler\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"pgrep -f bot_scheduler || exit 1\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 行情总线 (Market Publisher)\n market-publisher:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-market-pub\n restart: always\n command: python3 -m app.services.market_data_publisher\n environment:\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n depends_on:\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.market_data_publisher' in open('/proc/1/cmdline','rb').read() else 1)\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 风控守护 (Risk Monitor)\n risk-monitor:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-risk-monitor\n restart: always\n command: python3 -m app.services.risk_monitor\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"python -c \\\"import sys; sys.exit(0 if b'app.services.risk_monitor' in open('/proc/1/cmdline','rb').read() else 1)\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 交易执行器 (Celery Worker)\n trading-worker:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-trading-worker\n restart: always\n command: celery -A app.celery_app worker --loglevel=info -Q trading,celery --concurrency=1\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"celery -A app.celery_app inspect ping -d celery@$${HOSTNAME} || exit 1\"]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n # Celery Beat 定时任务调度器\n celery-beat:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: flowai-celery-beat\n restart: always\n command: celery -A app.celery_app beat --loglevel=info\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n environment:\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n OPENAI_API_KEY: ${OPENAI_API_KEY}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"python -c \\\"import sys; d=open('/proc/1/cmdline','rb').read(); sys.exit(0 if (b'celery' in d and b'beat' in d) else 1)\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 3\n start_period: 40s\n\n # 前端应用\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n container_name: crypto-ai-frontend\n restart: always\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-/api}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n NODE_ENV: production\n networks:\n - crypto-ai-network\n depends_on:\n backend:\n condition: service_healthy\n healthcheck:\n test: [\"CMD-SHELL\", \"node -e \\\"require('net').connect(3000,'127.0.0.1',()=>process.exit(0)).on('error',()=>process.exit(1))\\\"\"]\n interval: 30s\n timeout: 10s\n retries: 10\n start_period: 120s\n\n # Nginx反向代理\n nginx:\n image: nginx:alpine\n container_name: crypto-ai-nginx\n restart: always\n volumes:\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro\n - ./nginx/conf.d:/etc/nginx/conf.d:ro\n - ./nginx/ssl:/etc/nginx/ssl:ro\n - ./certbot/www:/var/www/certbot:ro\n - /data/nginx/logs:/var/log/nginx\n ports:\n - \"80:80\"\n - \"443:443\"\n networks:\n - crypto-ai-network\n depends_on:\n frontend:\n condition: service_healthy\n backend:\n condition: service_healthy\n healthcheck:\n test: [\"CMD\", \"nginx\", \"-t\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n\n"}, "35d7d78548bf60e7243d265f708a65ae858af96a": {"t": 1785749259.0959852, "n": 4283, "h": "ce16980041330457", "c": "version: '3.8'\n\nservices:\n # PostgreSQL数据库\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n ports:\n - \"5432:5432\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Redis缓存\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n command: redis-server --requirepass ${REDIS_PASSWORD}\n volumes:\n - /data/redis:/data\n ports:\n - \"6379:6379\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"-a\", \"${REDIS_PASSWORD}\", \"ping\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Qdrant向量数据库\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n volumes:\n - /data/qdrant:/qdrant/storage\n ports:\n - \"6333:6333\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:6333/health\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # 后端API\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n restart: always\n environment:\n # 数据库配置\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n \n # API密钥\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n API_KEY_ENCRYPTION_SECRET: ${API_KEY_ENCRYPTION_SECRET}\n ENCRYPTION_KEY: ${ENCRYPTION_KEY}\n NOWPAYMENTS_API_KEY: ${NOWPAYMENTS_API_KEY}\n NOWPAYMENTS_IPN_SECRET: ${NOWPAYMENTS_IPN_SECRET}\n \n # JWT配置\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n JWT_ALGORITHM: HS256\n JWT_EXPIRE_MINUTES: 10080\n \n # 应用配置\n ENVIRONMENT: production\n LOG_LEVEL: info\n CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n ports:\n - \"8000:8000\"\n networks:\n - crypto-ai-network\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 前端应用\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8000}\n container_name: crypto-ai-frontend\n restart: always\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8000}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n NODE_ENV: production\n ports:\n - \"3000:3000\"\n networks:\n - crypto-ai-network\n depends_on:\n - backend\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:3000\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # Nginx反向代理\n nginx:\n image: nginx:alpine\n container_name: crypto-ai-nginx\n restart: always\n volumes:\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro\n - ./nginx/ssl:/etc/nginx/ssl:ro\n - /data/nginx/logs:/var/log/nginx\n ports:\n - \"80:80\"\n - \"443:443\"\n networks:\n - crypto-ai-network\n depends_on:\n - frontend\n - backend\n healthcheck:\n test: [\"CMD\", \"nginx\", \"-t\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n\n"}, "75cf65ede6ea4a657bc66d2f4de6cc6d14f8559e": {"t": 1785749260.1877594, "n": 4194, "h": "a24e6d1ce28115d8", "c": "version: '3.8'\n\nservices:\n # PostgreSQL数据库\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}\n volumes:\n - /data/postgres:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n ports:\n - \"5432:5432\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Redis缓存\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n command: redis-server --requirepass ${REDIS_PASSWORD:-redis123}\n volumes:\n - /data/redis:/data\n ports:\n - \"6379:6379\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"ping\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Qdrant向量数据库\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n volumes:\n - /data/qdrant:/qdrant/storage\n ports:\n - \"6333:6333\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:6333/health\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # 后端API\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n restart: always\n environment:\n # 数据库配置\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD:-redis123}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n \n # API密钥\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n NOWPAYMENTS_API_KEY: ${NOWPAYMENTS_API_KEY}\n NOWPAYMENTS_IPN_SECRET: ${NOWPAYMENTS_IPN_SECRET}\n \n # JWT配置\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n JWT_ALGORITHM: HS256\n JWT_EXPIRE_MINUTES: 10080\n \n # 应用配置\n ENVIRONMENT: production\n LOG_LEVEL: info\n CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}\n volumes:\n - /data/backend/user_data:/app/user_data\n - /data/backend/logs:/app/logs\n ports:\n - \"8000:8000\"\n networks:\n - crypto-ai-network\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 前端应用\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8000}\n container_name: crypto-ai-frontend\n restart: always\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8000}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n NODE_ENV: production\n ports:\n - \"3000:3000\"\n networks:\n - crypto-ai-network\n depends_on:\n - backend\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:3000\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # Nginx反向代理\n nginx:\n image: nginx:alpine\n container_name: crypto-ai-nginx\n restart: always\n volumes:\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro\n - ./nginx/ssl:/etc/nginx/ssl:ro\n - /data/nginx/logs:/var/log/nginx\n ports:\n - \"80:80\"\n - \"443:443\"\n networks:\n - crypto-ai-network\n depends_on:\n - frontend\n - backend\n healthcheck:\n test: [\"CMD\", \"nginx\", \"-t\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n\n"}, "c508b7aa6183c7f7e116f521961e37497f443375": {"t": 1785749261.262538, "n": 4289, "h": "cf1b3a9dd90c0826", "c": "version: '3.8'\n\nservices:\n # PostgreSQL数据库\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}\n volumes:\n - postgres_data:/var/lib/postgresql/data\n - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql\n - ./database/migrations/002_add_vercel_compat_fields.sql:/docker-entrypoint-initdb.d/002_add_vercel_compat_fields.sql\n - ./database/migrations/003_add_document_vote_suggestion_stream_tables.sql:/docker-entrypoint-initdb.d/003_add_document_vote_suggestion_stream_tables.sql\n ports:\n - \"5432:5432\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Redis缓存\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n command: redis-server --requirepass ${REDIS_PASSWORD:-redis123}\n volumes:\n - redis_data:/data\n ports:\n - \"6379:6379\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"ping\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Qdrant向量数据库\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n volumes:\n - qdrant_data:/qdrant/storage\n ports:\n - \"6333:6333\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:6333/health\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # 后端API\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n restart: always\n environment:\n # 数据库配置\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD:-redis123}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n \n # API密钥\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n NOWPAYMENTS_API_KEY: ${NOWPAYMENTS_API_KEY}\n NOWPAYMENTS_IPN_SECRET: ${NOWPAYMENTS_IPN_SECRET}\n \n # JWT配置\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n JWT_ALGORITHM: HS256\n JWT_EXPIRE_MINUTES: 10080\n \n # 应用配置\n ENVIRONMENT: production\n LOG_LEVEL: info\n CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}\n volumes:\n - ./backend/user_data:/app/user_data\n - ./backend/logs:/app/logs\n ports:\n - \"8000:8000\"\n networks:\n - crypto-ai-network\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 前端应用\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8000}\n container_name: crypto-ai-frontend\n restart: always\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8000}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n NODE_ENV: production\n ports:\n - \"3000:3000\"\n networks:\n - crypto-ai-network\n depends_on:\n - backend\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:3000\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # Nginx反向代理\n nginx:\n image: nginx:alpine\n container_name: crypto-ai-nginx\n restart: always\n volumes:\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro\n - ./nginx/ssl:/etc/nginx/ssl:ro\n - ./nginx/logs:/var/log/nginx\n ports:\n - \"80:80\"\n - \"443:443\"\n networks:\n - crypto-ai-network\n depends_on:\n - frontend\n - backend\n healthcheck:\n test: [\"CMD\", \"nginx\", \"-t\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\nvolumes:\n postgres_data:\n driver: local\n redis_data:\n driver: local\n qdrant_data:\n driver: local\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n\n"}, "a02ce3e68421d71ed6d4a82c16043a76fce1b052": {"t": 1785749262.4233186, "n": 4013, "h": "0e20faea56c7032f", "c": "version: '3.8'\n\nservices:\n # PostgreSQL数据库\n postgres:\n image: postgres:15-alpine\n container_name: crypto-ai-postgres\n restart: always\n environment:\n POSTGRES_DB: ${POSTGRES_DB:-crypto_ai}\n POSTGRES_USER: ${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}\n volumes:\n - postgres_data:/var/lib/postgresql/data\n - ./backend/database/init.sql:/docker-entrypoint-initdb.d/init.sql\n ports:\n - \"5432:5432\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Redis缓存\n redis:\n image: redis:7-alpine\n container_name: crypto-ai-redis\n restart: always\n command: redis-server --requirepass ${REDIS_PASSWORD:-redis123}\n volumes:\n - redis_data:/data\n ports:\n - \"6379:6379\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"ping\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # Qdrant向量数据库\n qdrant:\n image: qdrant/qdrant:latest\n container_name: crypto-ai-qdrant\n restart: always\n volumes:\n - qdrant_data:/qdrant/storage\n ports:\n - \"6333:6333\"\n networks:\n - crypto-ai-network\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:6333/health\"]\n interval: 10s\n timeout: 5s\n retries: 5\n\n # 后端API\n backend:\n build:\n context: ./backend\n dockerfile: Dockerfile\n container_name: crypto-ai-backend\n restart: always\n environment:\n # 数据库配置\n DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-crypto_ai}\n REDIS_URL: redis://:${REDIS_PASSWORD:-redis123}@redis:6379/0\n QDRANT_URL: http://qdrant:6333\n \n # API密钥\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}\n NOWPAYMENTS_API_KEY: ${NOWPAYMENTS_API_KEY}\n NOWPAYMENTS_IPN_SECRET: ${NOWPAYMENTS_IPN_SECRET}\n \n # JWT配置\n JWT_SECRET_KEY: ${JWT_SECRET_KEY}\n JWT_ALGORITHM: HS256\n JWT_EXPIRE_MINUTES: 10080\n \n # 应用配置\n ENVIRONMENT: production\n LOG_LEVEL: info\n CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}\n volumes:\n - ./backend/user_data:/app/user_data\n - ./backend/logs:/app/logs\n ports:\n - \"8000:8000\"\n networks:\n - crypto-ai-network\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_healthy\n qdrant:\n condition: service_healthy\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8000/health\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # 前端应用\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n args:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8000}\n container_name: crypto-ai-frontend\n restart: always\n environment:\n NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8000}\n BACKEND_API_URL: http://backend:8000\n AUTH_SECRET: ${AUTH_SECRET}\n NODE_ENV: production\n ports:\n - \"3000:3000\"\n networks:\n - crypto-ai-network\n depends_on:\n - backend\n healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:3000\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\n # Nginx反向代理\n nginx:\n image: nginx:alpine\n container_name: crypto-ai-nginx\n restart: always\n volumes:\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro\n - ./nginx/ssl:/etc/nginx/ssl:ro\n - ./nginx/logs:/var/log/nginx\n ports:\n - \"80:80\"\n - \"443:443\"\n networks:\n - crypto-ai-network\n depends_on:\n - frontend\n - backend\n healthcheck:\n test: [\"CMD\", \"nginx\", \"-t\"]\n interval: 30s\n timeout: 10s\n retries: 3\n\nvolumes:\n postgres_data:\n driver: local\n redis_data:\n driver: local\n qdrant_data:\n driver: local\n\nnetworks:\n crypto-ai-network:\n driver: bridge\n\n"}}}}