|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# ═══════════════════════════════════════════════════════════════ |
| 4 | +# NOFX AI Trading System - Dev Branch Docker Start Script |
| 5 | +# Usage: ./start-dev.sh [command] |
| 6 | +# ═══════════════════════════════════════════════════════════════ |
| 7 | + |
| 8 | +set -e |
| 9 | + |
| 10 | +# ------------------------------------------------------------------------ |
| 11 | +# Color Definitions |
| 12 | +# ------------------------------------------------------------------------ |
| 13 | +RED='\033[0;31m' |
| 14 | +GREEN='\033[0;32m' |
| 15 | +YELLOW='\033[1;33m' |
| 16 | +BLUE='\033[0;34m' |
| 17 | +NC='\033[0m' # No Color |
| 18 | + |
| 19 | +# ------------------------------------------------------------------------ |
| 20 | +# Utility Functions: Colored Output |
| 21 | +# ------------------------------------------------------------------------ |
| 22 | +print_info() { |
| 23 | + echo -e "${BLUE}[INFO]${NC} $1" |
| 24 | +} |
| 25 | + |
| 26 | +print_success() { |
| 27 | + echo -e "${GREEN}[SUCCESS]${NC} $1" |
| 28 | +} |
| 29 | + |
| 30 | +print_warning() { |
| 31 | + echo -e "${YELLOW}[WARNING]${NC} $1" |
| 32 | +} |
| 33 | + |
| 34 | +print_error() { |
| 35 | + echo -e "${RED}[ERROR]${NC} $1" |
| 36 | +} |
| 37 | + |
| 38 | +# ------------------------------------------------------------------------ |
| 39 | +# Detection: Docker Compose Command |
| 40 | +# ------------------------------------------------------------------------ |
| 41 | +detect_compose_cmd() { |
| 42 | + if command -v docker compose &> /dev/null; then |
| 43 | + COMPOSE_CMD="docker compose -f docker-compose.dev.yml --env-file .env.dev" |
| 44 | + elif command -v docker-compose &> /dev/null; then |
| 45 | + COMPOSE_CMD="docker-compose -f docker-compose.dev.yml --env-file .env.dev" |
| 46 | + else |
| 47 | + print_error "Docker Compose 未安装!请先安装 Docker Compose" |
| 48 | + exit 1 |
| 49 | + fi |
| 50 | + print_info "使用 Docker Compose 命令: $COMPOSE_CMD" |
| 51 | +} |
| 52 | + |
| 53 | +# ------------------------------------------------------------------------ |
| 54 | +# Validation: Docker Installation |
| 55 | +# ------------------------------------------------------------------------ |
| 56 | +check_docker() { |
| 57 | + if ! command -v docker &> /dev/null; then |
| 58 | + print_error "Docker 未安装!请先安装 Docker: https://docs.docker.com/get-docker/" |
| 59 | + exit 1 |
| 60 | + fi |
| 61 | + |
| 62 | + detect_compose_cmd |
| 63 | + print_success "Docker 和 Docker Compose 已安装" |
| 64 | +} |
| 65 | + |
| 66 | +# ------------------------------------------------------------------------ |
| 67 | +# Validation: Environment File (.env.dev) |
| 68 | +# ------------------------------------------------------------------------ |
| 69 | +check_env() { |
| 70 | + if [ ! -f ".env.dev" ]; then |
| 71 | + print_warning ".env.dev 不存在,从模板复制..." |
| 72 | + if [ -f ".env.example" ]; then |
| 73 | + cp .env.example .env.dev |
| 74 | + # 修改为 dev 环境的默认端口 |
| 75 | + sed -i 's/^NOFX_BACKEND_PORT=.*/NOFX_BACKEND_PORT=8081/' .env.dev |
| 76 | + sed -i 's/^NOFX_FRONTEND_PORT=.*/NOFX_FRONTEND_PORT=3001/' .env.dev |
| 77 | + else |
| 78 | + # 创建默认的 .env.dev 文件,使用 dev 分支的端口 |
| 79 | + cat > .env.dev << EOF |
| 80 | +# NOFX Environment Variables - Dev Environment |
| 81 | +# This file is used by docker-compose.dev.yml for development environment |
| 82 | +
|
| 83 | +# Ports Configuration |
| 84 | +# Dev environment uses different ports to avoid conflict with production (main branch) |
| 85 | +NOFX_BACKEND_PORT=8081 |
| 86 | +NOFX_FRONTEND_PORT=3001 |
| 87 | +
|
| 88 | +# Timezone Setting |
| 89 | +NOFX_TIMEZONE=Asia/Shanghai |
| 90 | +EOF |
| 91 | + fi |
| 92 | + print_info "✓ 已使用默认环境变量创建 .env.dev" |
| 93 | + print_info "💡 Dev 版本使用端口:前端 3001,后端 8081" |
| 94 | + fi |
| 95 | + print_success "环境变量文件存在 (.env.dev)" |
| 96 | +} |
| 97 | + |
| 98 | +# ------------------------------------------------------------------------ |
| 99 | +# Validation: Configuration File (config.json) |
| 100 | +# ------------------------------------------------------------------------ |
| 101 | +check_config() { |
| 102 | + if [ ! -f "config.json" ]; then |
| 103 | + print_warning "config.json 不存在,从模板复制..." |
| 104 | + cp config.json.example config.json |
| 105 | + print_info "✓ 已使用默认配置创建 config.json" |
| 106 | + fi |
| 107 | + print_success "配置文件存在" |
| 108 | +} |
| 109 | + |
| 110 | +# ------------------------------------------------------------------------ |
| 111 | +# Validation: Database File (config.db.dev) |
| 112 | +# ------------------------------------------------------------------------ |
| 113 | +check_database() { |
| 114 | + if [ ! -f "config.db.dev" ]; then |
| 115 | + print_warning "Dev 数据库文件不存在,创建空数据库文件..." |
| 116 | + touch config.db.dev |
| 117 | + print_info "✓ 已创建空数据库文件,系统将在启动时初始化" |
| 118 | + fi |
| 119 | + print_success "数据库文件存在" |
| 120 | +} |
| 121 | + |
| 122 | +# ------------------------------------------------------------------------ |
| 123 | +# Utility: Read Environment Variables |
| 124 | +# ------------------------------------------------------------------------ |
| 125 | +read_env_vars() { |
| 126 | + if [ -f ".env.dev" ]; then |
| 127 | + NOFX_FRONTEND_PORT=$(grep "^NOFX_FRONTEND_PORT=" .env.dev 2>/dev/null | cut -d'=' -f2 || echo "3001") |
| 128 | + NOFX_BACKEND_PORT=$(grep "^NOFX_BACKEND_PORT=" .env.dev 2>/dev/null | cut -d'=' -f2 || echo "8081") |
| 129 | + |
| 130 | + NOFX_FRONTEND_PORT=$(echo "$NOFX_FRONTEND_PORT" | tr -d '"' | tr -d ' ') |
| 131 | + NOFX_BACKEND_PORT=$(echo "$NOFX_BACKEND_PORT" | tr -d '"' | tr -d ' ') |
| 132 | + |
| 133 | + NOFX_FRONTEND_PORT=${NOFX_FRONTEND_PORT:-3001} |
| 134 | + NOFX_BACKEND_PORT=${NOFX_BACKEND_PORT:-8081} |
| 135 | + else |
| 136 | + NOFX_FRONTEND_PORT=3001 |
| 137 | + NOFX_BACKEND_PORT=8081 |
| 138 | + fi |
| 139 | +} |
| 140 | + |
| 141 | +# ------------------------------------------------------------------------ |
| 142 | +# Service Management: Start |
| 143 | +# ------------------------------------------------------------------------ |
| 144 | +start() { |
| 145 | + print_info "正在启动 NOFX AI Trading System (Dev 分支)..." |
| 146 | + |
| 147 | + # 读取环境变量 |
| 148 | + read_env_vars |
| 149 | + |
| 150 | + # Rebuild images if flag set |
| 151 | + if [ "$1" == "--build" ]; then |
| 152 | + print_info "重新构建镜像..." |
| 153 | + $COMPOSE_CMD up -d --build |
| 154 | + else |
| 155 | + print_info "启动容器..." |
| 156 | + $COMPOSE_CMD up -d |
| 157 | + fi |
| 158 | + |
| 159 | + print_success "服务已启动!" |
| 160 | + print_info "Web 界面: http://localhost:${NOFX_FRONTEND_PORT}" |
| 161 | + print_info "API 端点: http://localhost:${NOFX_BACKEND_PORT}" |
| 162 | + print_info "" |
| 163 | + print_info "查看日志: ./start-dev.sh logs" |
| 164 | + print_info "停止服务: ./start-dev.sh stop" |
| 165 | +} |
| 166 | + |
| 167 | +# ------------------------------------------------------------------------ |
| 168 | +# Service Management: Stop |
| 169 | +# ------------------------------------------------------------------------ |
| 170 | +stop() { |
| 171 | + print_info "正在停止服务..." |
| 172 | + $COMPOSE_CMD stop |
| 173 | + print_success "服务已停止" |
| 174 | +} |
| 175 | + |
| 176 | +# ------------------------------------------------------------------------ |
| 177 | +# Service Management: Restart |
| 178 | +# ------------------------------------------------------------------------ |
| 179 | +restart() { |
| 180 | + print_info "正在重启服务..." |
| 181 | + $COMPOSE_CMD restart |
| 182 | + print_success "服务已重启" |
| 183 | +} |
| 184 | + |
| 185 | +# ------------------------------------------------------------------------ |
| 186 | +# Monitoring: Logs |
| 187 | +# ------------------------------------------------------------------------ |
| 188 | +logs() { |
| 189 | + if [ -z "$2" ]; then |
| 190 | + $COMPOSE_CMD logs -f |
| 191 | + else |
| 192 | + $COMPOSE_CMD logs -f "$2" |
| 193 | + fi |
| 194 | +} |
| 195 | + |
| 196 | +# ------------------------------------------------------------------------ |
| 197 | +# Monitoring: Status |
| 198 | +# ------------------------------------------------------------------------ |
| 199 | +status() { |
| 200 | + read_env_vars |
| 201 | + |
| 202 | + print_info "服务状态:" |
| 203 | + $COMPOSE_CMD ps |
| 204 | + echo "" |
| 205 | + print_info "健康检查:" |
| 206 | + curl -s "http://localhost:${NOFX_BACKEND_PORT}/api/health" | jq '.' || echo "后端未响应" |
| 207 | +} |
| 208 | + |
| 209 | +# ------------------------------------------------------------------------ |
| 210 | +# Maintenance: Clean |
| 211 | +# ------------------------------------------------------------------------ |
| 212 | +clean() { |
| 213 | + print_warning "这将删除所有 Dev 容器和数据!" |
| 214 | + read -p "确认删除?(yes/no): " confirm |
| 215 | + if [ "$confirm" == "yes" ]; then |
| 216 | + print_info "正在清理..." |
| 217 | + $COMPOSE_CMD down -v |
| 218 | + print_success "清理完成" |
| 219 | + else |
| 220 | + print_info "已取消" |
| 221 | + fi |
| 222 | +} |
| 223 | + |
| 224 | +# ------------------------------------------------------------------------ |
| 225 | +# Help: Usage Information |
| 226 | +# ------------------------------------------------------------------------ |
| 227 | +show_help() { |
| 228 | + echo "NOFX AI Trading System (Dev) - Docker 管理脚本" |
| 229 | + echo "" |
| 230 | + echo "用法: ./start-dev.sh [command] [options]" |
| 231 | + echo "" |
| 232 | + echo "命令:" |
| 233 | + echo " start [--build] 启动服务(可选:重新构建)" |
| 234 | + echo " stop 停止服务" |
| 235 | + echo " restart 重启服务" |
| 236 | + echo " logs [service] 查看日志(可选:指定服务名 nofx/nofx-frontend)" |
| 237 | + echo " status 查看服务状态" |
| 238 | + echo " clean 清理所有容器和数据" |
| 239 | + echo " help 显示此帮助信息" |
| 240 | + echo "" |
| 241 | + echo "端口配置:" |
| 242 | + echo " - 前端: 3001 (避免与 main 分支的 3000 冲突)" |
| 243 | + echo " - 后端: 8081 (避免与 main 分支的 8080 冲突)" |
| 244 | + echo "" |
| 245 | + echo "数据文件:" |
| 246 | + echo " - 数据库: config.db.dev (独立的 dev 数据库)" |
| 247 | + echo " - 日志: decision_logs.dev/ (独立的 dev 日志目录)" |
| 248 | + echo " - 环境变量: .env.dev (独立的 dev 环境配置,与 main 分支的 .env 分离)" |
| 249 | +} |
| 250 | + |
| 251 | +# ------------------------------------------------------------------------ |
| 252 | +# Main: Command Dispatcher |
| 253 | +# ------------------------------------------------------------------------ |
| 254 | +main() { |
| 255 | + check_docker |
| 256 | + |
| 257 | + case "${1:-start}" in |
| 258 | + start) |
| 259 | + check_env |
| 260 | + check_config |
| 261 | + check_database |
| 262 | + start "$2" |
| 263 | + ;; |
| 264 | + stop) |
| 265 | + stop |
| 266 | + ;; |
| 267 | + restart) |
| 268 | + restart |
| 269 | + ;; |
| 270 | + logs) |
| 271 | + logs "$@" |
| 272 | + ;; |
| 273 | + status) |
| 274 | + status |
| 275 | + ;; |
| 276 | + clean) |
| 277 | + clean |
| 278 | + ;; |
| 279 | + help|--help|-h) |
| 280 | + show_help |
| 281 | + ;; |
| 282 | + *) |
| 283 | + print_error "未知命令: $1" |
| 284 | + show_help |
| 285 | + exit 1 |
| 286 | + ;; |
| 287 | + esac |
| 288 | +} |
| 289 | + |
| 290 | +# Execute Main |
| 291 | +main "$@" |
| 292 | + |
0 commit comments