deploy.sh 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #!/bin/bash
  2. set -e # 出错时终止脚本
  3. # 配置信息
  4. APP_DIR="/root/AutoScraperX"
  5. LOG_FILE="${APP_DIR}/logs/autoscraperx_deploy.log" # 部署日志路径(统一到项目logs目录)
  6. VENV_DIR="${APP_DIR}/venv" # 虚拟环境路径(与项目中实际venv目录对应)
  7. PYTHON="${VENV_DIR}/bin/python" # 虚拟环境Python解释器
  8. PIP="${VENV_DIR}/bin/pip" # 虚拟环境pip工具
  9. REQUIREMENTS="${APP_DIR}/requirements.txt"
  10. STARTUP_LOG="${APP_DIR}/logs/main_startup.log" # 服务启动日志
  11. # 日志函数
  12. log() {
  13. local msg="[$(date '+%Y-%m-%d %H:%M:%S')] $1"
  14. echo "$msg"
  15. echo "$msg" >> "$LOG_FILE"
  16. }
  17. # 错误处理函数
  18. handle_error() {
  19. log "部署失败: $1"
  20. exit 1
  21. }
  22. # 确保目录存在
  23. ensure_dir() {
  24. if [ ! -d "$1" ]; then
  25. log "创建目录: $1"
  26. mkdir -p "$1" || handle_error "无法创建目录 $1"
  27. fi
  28. }
  29. # 检查文件权限
  30. check_permission() {
  31. if [ ! -x "$1" ]; then
  32. log "修复文件权限: $1"
  33. chmod +x "$1" || handle_error "无法修复 $1 权限"
  34. fi
  35. }
  36. # 主函数
  37. main() {
  38. # 前置检查:确保项目目录存在
  39. ensure_dir "$APP_DIR"
  40. ensure_dir "${APP_DIR}/logs" # 确保日志目录存在
  41. check_permission "${APP_DIR}/run.sh" # 修复run.sh权限
  42. log "===== 开始部署 AutoScraperX ====="
  43. cd "$APP_DIR" || handle_error "应用目录不存在: $APP_DIR"
  44. # 拉取最新代码(如果是Git仓库)
  45. log "拉取最新代码..."
  46. if [ -d ".git" ]; then
  47. git pull origin master || handle_error "Git拉取失败"
  48. else
  49. log "警告: 当前目录不是Git仓库,跳过拉取"
  50. fi
  51. # 创建或更新虚拟环境
  52. log "检查虚拟环境..."
  53. if [ ! -d "$VENV_DIR" ]; then
  54. log "创建新的虚拟环境..."
  55. python3 -m venv "$VENV_DIR" || handle_error "创建虚拟环境失败"
  56. fi
  57. # 安装依赖(使用虚拟环境pip)
  58. log "安装Python依赖..."
  59. "$PIP" install --upgrade pip || handle_error "更新pip失败"
  60. "$PIP" install -r "$REQUIREMENTS" || handle_error "安装依赖失败"
  61. # 停止现有服务(精准匹配虚拟环境Python)
  62. log "停止现有服务..."
  63. pkill -f "${PYTHON} main.py" || true # 忽略"无进程可杀"的错误
  64. sleep 2 # 等待进程终止
  65. # 启动服务(输出日志到文件,便于排查)
  66. log "启动新服务...(日志: ${STARTUP_LOG})"
  67. nohup "${PYTHON}" main.py > "${STARTUP_LOG}" 2>&1 &
  68. sleep 3 # 延长等待时间,确保服务有足够时间启动
  69. # 检查服务状态(更可靠的检测方式)
  70. if ps aux | grep -v grep | grep -E "${PYTHON}.*main\.py" > /dev/null; then
  71. log "服务已成功启动!"
  72. else
  73. # 启动失败时,输出启动日志片段帮助排查
  74. log "服务启动失败!启动日志最后10行:"
  75. tail -n 10 "${STARTUP_LOG}" >> "$LOG_FILE" # 将启动日志尾部写入部署日志
  76. handle_error "服务启动失败,详情见启动日志: ${STARTUP_LOG}"
  77. fi
  78. log "===== 部署完成 ====="
  79. }
  80. # 执行主函数
  81. main