deploy.sh 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #!/bin/bash
  2. # ============================================
  3. # 一键部署脚本 (Linux)
  4. # 用于服务器环境部署前后端
  5. # ============================================
  6. set -e
  7. # 颜色定义
  8. RED='\033[0;31m'
  9. GREEN='\033[0;32m'
  10. YELLOW='\033[1;33m'
  11. NC='\033[0m'
  12. # 配置变量(根据实际情况修改)
  13. FRONTEND_DEPLOY_DIR="/home/lq/nginx/html_app/lq_label" # 前端部署目录(Nginx root)
  14. GIT_BRANCH="main" # Git 分支
  15. echo -e "${GREEN}============================================${NC}"
  16. echo -e "${GREEN} LQ Label 一键部署脚本${NC}"
  17. echo -e "${GREEN}============================================${NC}"
  18. echo
  19. # 获取脚本所在目录
  20. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  21. cd "$SCRIPT_DIR"
  22. # ============================================
  23. # 1. 拉取最新代码
  24. # ============================================
  25. echo -e "${YELLOW}[1/4] 拉取最新代码...${NC}"
  26. if [ -d ".git" ]; then
  27. git fetch origin
  28. git checkout $GIT_BRANCH
  29. git pull origin $GIT_BRANCH
  30. echo -e "${GREEN}代码更新完成${NC}"
  31. else
  32. echo -e "${RED}错误: 当前目录不是 Git 仓库${NC}"
  33. exit 1
  34. fi
  35. # ============================================
  36. # 2. 部署后端 (Docker)
  37. # ============================================
  38. echo
  39. echo -e "${YELLOW}[2/4] 部署后端服务...${NC}"
  40. cd backend
  41. # 检查配置文件
  42. if [ ! -f "config.yaml" ]; then
  43. echo -e "${YELLOW}未找到 config.yaml,从模板创建...${NC}"
  44. cp config.docker.yaml config.yaml
  45. echo -e "${RED}请编辑 backend/config.yaml 配置数据库和密钥后重新运行${NC}"
  46. exit 1
  47. fi
  48. # 创建数据目录
  49. mkdir -p data
  50. # 检查是否需要重新构建镜像
  51. NEED_BUILD=false
  52. NEED_FULL_BUILD=false
  53. # 检查镜像是否存在
  54. if ! docker image inspect lq-label-backend:latest > /dev/null 2>&1; then
  55. echo "镜像不存在,需要完整构建..."
  56. NEED_BUILD=true
  57. NEED_FULL_BUILD=true
  58. fi
  59. # 计算当前代码哈希(包含所有 Python 文件)
  60. # 依赖文件哈希(变更需要完整重建)
  61. DEPS_HASH=$(md5sum requirements.txt Dockerfile 2>/dev/null | md5sum | cut -d' ' -f1)
  62. # 代码文件哈希(变更只需增量重建)
  63. CODE_HASH=$(find . -name "*.py" -type f ! -path "./.pytest_cache/*" ! -path "./__pycache__/*" -exec md5sum {} \; 2>/dev/null | sort | md5sum | cut -d' ' -f1)
  64. # 检查依赖是否变更(需要完整重建,不使用缓存)
  65. if [ -f ".last_deps_hash" ]; then
  66. LAST_DEPS_HASH=$(cat .last_deps_hash)
  67. if [ "$DEPS_HASH" != "$LAST_DEPS_HASH" ]; then
  68. echo "检测到依赖或 Dockerfile 变更,需要完整重建..."
  69. NEED_BUILD=true
  70. NEED_FULL_BUILD=true
  71. fi
  72. else
  73. NEED_BUILD=true
  74. NEED_FULL_BUILD=true
  75. fi
  76. # 检查代码是否变更(增量重建,使用缓存)
  77. if [ -f ".last_code_hash" ]; then
  78. LAST_CODE_HASH=$(cat .last_code_hash)
  79. if [ "$CODE_HASH" != "$LAST_CODE_HASH" ]; then
  80. echo "检测到 Python 代码变更,需要增量重建..."
  81. NEED_BUILD=true
  82. fi
  83. else
  84. NEED_BUILD=true
  85. fi
  86. # 执行构建
  87. if [ "$NEED_BUILD" = true ]; then
  88. if [ "$NEED_FULL_BUILD" = true ]; then
  89. echo "执行完整构建(不使用缓存)..."
  90. docker build --no-cache -t lq-label-backend:latest .
  91. else
  92. echo "执行增量构建(使用缓存加速)..."
  93. docker build -t lq-label-backend:latest .
  94. fi
  95. # 保存哈希
  96. echo "$DEPS_HASH" > .last_deps_hash
  97. echo "$CODE_HASH" > .last_code_hash
  98. echo -e "${GREEN}镜像构建完成${NC}"
  99. else
  100. echo "代码无变更,跳过构建"
  101. fi
  102. echo "启动后端服务..."
  103. docker compose down 2>/dev/null || true
  104. docker compose up -d
  105. # 等待服务启动
  106. echo "等待服务启动..."
  107. sleep 5
  108. # 健康检查
  109. if curl -s http://localhost:8003/health > /dev/null; then
  110. echo -e "${GREEN}后端服务启动成功${NC}"
  111. else
  112. echo -e "${RED}后端服务启动失败,请检查日志: docker compose logs${NC}"
  113. exit 1
  114. fi
  115. cd "$SCRIPT_DIR"
  116. # ============================================
  117. # 3. 部署前端
  118. # ============================================
  119. echo
  120. echo -e "${YELLOW}[3/4] 部署前端...${NC}"
  121. # 检查前端包是否存在
  122. if [ ! -f "lq_label_dist.tar.gz" ]; then
  123. echo -e "${RED}错误: 未找到 lq_label_dist.tar.gz${NC}"
  124. echo -e "${YELLOW}请先在 Windows 开发环境运行 build.bat 构建前端${NC}"
  125. exit 1
  126. fi
  127. # 创建部署目录
  128. sudo mkdir -p "$FRONTEND_DEPLOY_DIR"
  129. # 备份旧版本(可选)
  130. if [ -d "$FRONTEND_DEPLOY_DIR" ] && [ "$(ls -A $FRONTEND_DEPLOY_DIR 2>/dev/null)" ]; then
  131. BACKUP_DIR="${FRONTEND_DEPLOY_DIR}_backup_$(date +%Y%m%d_%H%M%S)"
  132. echo "备份旧版本到 $BACKUP_DIR"
  133. sudo mv "$FRONTEND_DEPLOY_DIR" "$BACKUP_DIR"
  134. sudo mkdir -p "$FRONTEND_DEPLOY_DIR"
  135. fi
  136. # 解压前端文件
  137. echo "解压前端文件到 $FRONTEND_DEPLOY_DIR"
  138. sudo tar -xzvf lq_label_dist.tar.gz -C "$FRONTEND_DEPLOY_DIR" --strip-components=1
  139. # 设置权限
  140. sudo chown -R www-data:www-data "$FRONTEND_DEPLOY_DIR" 2>/dev/null || \
  141. sudo chown -R nginx:nginx "$FRONTEND_DEPLOY_DIR" 2>/dev/null || \
  142. echo "请手动设置目录权限"
  143. echo -e "${GREEN}前端部署完成${NC}"
  144. # ============================================
  145. # 4. 重载 Nginx
  146. # ============================================
  147. echo
  148. echo -e "${YELLOW}[4/4] 重载 Nginx 配置...${NC}"
  149. # 检查 Nginx 配置
  150. if sudo nginx -t; then
  151. sudo systemctl reload nginx || sudo nginx -s reload
  152. echo -e "${GREEN}Nginx 重载完成${NC}"
  153. else
  154. echo -e "${RED}Nginx 配置错误,请检查配置文件${NC}"
  155. exit 1
  156. fi
  157. # ============================================
  158. # 完成
  159. # ============================================
  160. echo
  161. echo -e "${GREEN}============================================${NC}"
  162. echo -e "${GREEN} 部署完成!${NC}"
  163. echo -e "${GREEN}============================================${NC}"
  164. echo
  165. echo "前端地址: http://localhost:9101"
  166. echo "后端地址: http://localhost:8003"
  167. echo "API 文档: http://localhost:8003/docs"
  168. echo
  169. echo -e "${YELLOW}常用命令:${NC}"
  170. echo " 查看后端日志: cd backend && docker compose logs -f"
  171. echo " 重启后端: cd backend && docker compose restart"
  172. echo " 停止后端: cd backend && docker compose down"