#!/bin/bash # AI Flow Backend Docker 构建和部署脚本 # 适用于 Node.js + Midway.js + Cool Admin 项目 set -e # 遇到错误立即退出 # 项目配置 group_name='ai-flow' app_name='ai-flow-backend' app_version='latest' app_port=8002 # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 日志函数 log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } echo "" log_info "开始 AI Flow Backend 部署流程..." echo "========================================" # 检查 Docker 是否安装 if ! command -v docker &> /dev/null; then log_error "Docker 未安装,请先安装 Docker" exit 1 fi # 检查并删除旧容器和镜像 log_info "检查并清理旧容器和镜像..." if docker ps -a --format "{{.Names}}" | grep -q "^${app_name}$"; then log_warning "发现旧容器,正在删除..." docker rm -f ${app_name} docker rmi ${group_name}/${app_name}:${app_version} 2>/dev/null || true log_success "旧容器和镜像清理完成" else log_info "未发现旧容器" fi # 创建必要目录 log_info "创建必要目录..." mkdir -p /usr/local/ai-flow/uploads /usr/local/ai-flow/public /usr/local/ai-flow/cache # 构建Docker镜像 log_info "构建 Docker 镜像..." docker build -t ${group_name}/${app_name}:${app_version} . || { log_error "Docker 镜像构建失败" exit 1 } log_success "Docker 镜像构建完成" # 运行新容器 log_info "启动新容器..." docker run --name ${app_name} \ --restart unless-stopped \ -v /usr/local/ai-flow/uploads:/app/public/uploads \ -v /usr/local/ai-flow/public:/app/public \ -v /usr/local/ai-flow/cache:/app/cache \ -e NODE_ENV=local \ -e TZ=Asia/Shanghai \ -p ${app_port}:${app_port} \ -d ${group_name}/${app_name}:${app_version} \ sh -c 'NODE_ENV=local node ./bootstrap.js' || { log_error "容器启动失败" exit 1 } # 等待容器启动 log_info "等待容器启动..." sleep 20 # 检查容器状态 log_info "检查容器状态..." if docker ps --format "{{.Names}}" | grep -q "^${app_name}$"; then log_success "容器启动成功" docker ps -f name=${app_name} --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" else log_error "容器启动失败" docker logs ${app_name} exit 1 fi # 显示容器启动日志 log_info "容器启动日志:" docker logs --tail=20 ${app_name} # Node.js 应用健康检查 log_info "进行应用健康检查..." sleep 10 # 检查进程是否运行 if docker exec ${app_name} ps aux | grep -q "node.*bootstrap"; then log_success "Node.js 进程运行正常" else log_warning "Node.js 进程检查异常,查看详细日志" fi # 检查端口监听 log_info "检查端口监听状态..." if docker exec ${app_name} netstat -tlnp 2>/dev/null | grep -q ":${app_port}"; then log_success "端口 ${app_port} 监听正常" else log_warning "端口 ${app_port} 监听检查异常" docker exec ${app_name} netstat -tlnp 2>/dev/null || true fi # HTTP 健康检查 log_info "进行 HTTP 健康检查..." sleep 5 if curl -f -s "http://localhost:${app_port}/" >/dev/null 2>&1 || \ curl -f -s "http://localhost:${app_port}/ping" >/dev/null 2>&1 || \ docker exec ${app_name} wget -q --spider "http://localhost:${app_port}/" 2>/dev/null; then log_success "HTTP 健康检查通过" else log_warning "HTTP 健康检查失败,但服务可能仍在启动中" log_info "请手动检查服务状态: curl http://localhost:${app_port}/" fi # 检查依赖服务连接(如果配置了的话) log_info "检查应用配置..." if docker exec ${app_name} cat package.json | grep -q "cool-admin"; then log_success "Cool Admin 框架检测正常" fi if docker exec ${app_name} cat package.json | grep -q "typeorm"; then log_info "检测到 TypeORM,请确保数据库连接正常" fi if docker exec ${app_name} cat package.json | grep -q "redis"; then log_info "检测到 Redis 依赖,请确保 Redis 服务可用" fi echo "" log_success "🎉 AI Flow Backend 部署完成!" echo "========================================" echo "容器名称: ${app_name}" echo "访问地址: http://localhost:${app_port}" echo "管理后台: http://localhost:${app_port}/admin" echo "API 文档: http://localhost:${app_port}/api-docs" echo "" echo "常用命令:" echo "查看日志: docker logs -f ${app_name}" echo "进入容器: docker exec -it ${app_name} sh" echo "重启服务: docker restart ${app_name}" echo "停止服务: docker stop ${app_name}" echo "删除容器: docker rm -f ${app_name}" echo "" echo "文件挂载:" echo "上传目录: /usr/local/ai-flow/uploads" echo "静态文件: /usr/local/ai-flow/public" echo "缓存目录: /usr/local/ai-flow/cache" echo "========================================"