deploy.sh 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #!/usr/bin/env bash
  2. # =============================================================================
  3. # FranklinWH Toolbox - 一键构建 & 部署脚本(前端 + 后端)
  4. # =============================================================================
  5. # 作用:
  6. # 1. 构建前端(pnpm build)并同步到静态目录
  7. # 2. 构建后端主程序 fwh-toolbox-server 与 fwh-mcp-server,安装 systemd 服务
  8. # 3. 部署 Kiro CLI 配置(agents/settings/steering/skills)到 server/.kiro
  9. #
  10. # 目录约定(与线上服务器保持一致,可用环境变量覆盖):
  11. # DEPLOY_ROOT /var/www/fwh-toolbox
  12. # ├── fwh-toolbox/ 前端静态文件(构建产物 dist/*)
  13. # └── server/ 后端二进制 + config.env + config.mcp.env + cert/ + .kiro/(kiro-cli 配置)
  14. #
  15. # 用法:
  16. # ./deploy.sh all # 前端 + 后端 + Kiro 配置(默认)
  17. # ./deploy.sh frontend # 仅前端
  18. # ./deploy.sh backend # 仅后端
  19. # ./deploy.sh kiro # 仅 Kiro CLI 配置(含 skills 安装/拷贝)
  20. #
  21. # 前置条件:
  22. # - 已安装 Go、Node、pnpm(见 docs/DEPLOYMENT.md)
  23. # - service/config.env 已配置好(首次部署请从 config.env.example 复制)
  24. # =============================================================================
  25. set -euo pipefail
  26. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  27. DEPLOY_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" # deploy/
  28. PROJECT_ROOT="$(cd "${DEPLOY_DIR}/.." && pwd)" # 仓库根目录
  29. SERVICE_DIR="${PROJECT_ROOT}/service" # Go 后端目录
  30. CONFIG_EXAMPLE="${DEPLOY_DIR}/config.env.example" # 后端配置模板
  31. MCP_CONFIG_EXAMPLE="${DEPLOY_DIR}/config.mcp.env.example" # MCP 配置模板
  32. DEPLOY_ROOT="${DEPLOY_ROOT:-/var/www/fwh-toolbox}"
  33. FRONTEND_DIST_DIR="${DEPLOY_ROOT}/fwh-toolbox"
  34. SERVER_DIR="${DEPLOY_ROOT}/server"
  35. APP_NAME="fwh-toolbox-server"
  36. MCP_NAME="fwh-mcp-server"
  37. SERVICE_FILE="/etc/systemd/system/${APP_NAME}.service"
  38. RUN_USER="${RUN_USER:-jerry-remote}"
  39. # Kiro CLI 配置部署(AI 对话依赖):目标用户与 HOME 需与后端拉起 kiro-cli 时一致
  40. KIRO_RUN_AS_USER="${KIRO_RUN_AS_USER:-${RUN_USER}}"
  41. KIRO_HOME="${KIRO_HOME:-${SERVER_DIR}}"
  42. info() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
  43. ok() { echo -e "\033[1;32m[ OK ]\033[0m $*"; }
  44. # ---------------------------------------------------------------------------
  45. # 前端
  46. # ---------------------------------------------------------------------------
  47. deploy_frontend() {
  48. info "构建前端 ..."
  49. cd "${PROJECT_ROOT}"
  50. pnpm install --frozen-lockfile
  51. pnpm build
  52. sudo mkdir -p "${FRONTEND_DIST_DIR}"
  53. info "同步静态文件到 ${FRONTEND_DIST_DIR} ..."
  54. sudo rm -rf "${FRONTEND_DIST_DIR:?}/"*
  55. sudo cp -rf ./dist/* "${FRONTEND_DIST_DIR}/"
  56. ok "前端部署完成"
  57. }
  58. # ---------------------------------------------------------------------------
  59. # 后端
  60. # ---------------------------------------------------------------------------
  61. build_backend() {
  62. info "构建后端二进制 ..."
  63. cd "${SERVICE_DIR}"
  64. GOOS=linux GOARCH=amd64 go build -o "${APP_NAME}" ./
  65. GOOS=linux GOARCH=amd64 go build -o "${MCP_NAME}" ./cmd/mcp/
  66. ok "后端构建完成"
  67. }
  68. install_service() {
  69. if [[ ! -f "${SERVICE_FILE}" ]]; then
  70. info "创建 systemd 服务:${SERVICE_FILE}"
  71. sudo tee "${SERVICE_FILE}" > /dev/null <<EOF
  72. [Unit]
  73. Description=${APP_NAME} service
  74. After=network.target postgresql.service mongod.service redis-server.service minio.service
  75. [Service]
  76. ExecStart=${SERVER_DIR}/${APP_NAME}
  77. Restart=always
  78. User=${RUN_USER}
  79. WorkingDirectory=${SERVER_DIR}
  80. CPUQuota=200%
  81. MemoryLimit=2G
  82. [Install]
  83. WantedBy=multi-user.target
  84. EOF
  85. sudo systemctl daemon-reload
  86. sudo systemctl enable "${APP_NAME}"
  87. ok "systemd 服务已创建并设为开机自启"
  88. fi
  89. }
  90. deploy_backend() {
  91. build_backend
  92. sudo mkdir -p "${SERVER_DIR}"
  93. info "安装二进制到 ${SERVER_DIR} ..."
  94. sudo mv "${SERVICE_DIR}/${APP_NAME}" "${SERVER_DIR}/${APP_NAME}"
  95. sudo mv "${SERVICE_DIR}/${MCP_NAME}" "${SERVER_DIR}/${MCP_NAME}"
  96. sudo chmod +x "${SERVER_DIR}/${APP_NAME}" "${SERVER_DIR}/${MCP_NAME}"
  97. if [[ ! -f "${SERVER_DIR}/config.env" ]]; then
  98. info "未发现 ${SERVER_DIR}/config.env,从示例模板复制(请务必修改其中的密钥)"
  99. sudo cp "${CONFIG_EXAMPLE}" "${SERVER_DIR}/config.env"
  100. fi
  101. if [[ ! -f "${SERVER_DIR}/config.mcp.env" ]]; then
  102. info "未发现 ${SERVER_DIR}/config.mcp.env,从示例模板复制(MCP 独立配置,请务必修改其中的密钥)"
  103. sudo cp "${MCP_CONFIG_EXAMPLE}" "${SERVER_DIR}/config.mcp.env"
  104. fi
  105. install_service
  106. if systemctl is-active --quiet "${APP_NAME}"; then
  107. info "重启 ${APP_NAME} ..."
  108. sudo systemctl restart "${APP_NAME}"
  109. else
  110. info "启动 ${APP_NAME} ..."
  111. sudo systemctl start "${APP_NAME}"
  112. fi
  113. sudo systemctl status "${APP_NAME}" --no-pager || true
  114. ok "后端部署完成"
  115. }
  116. # ---------------------------------------------------------------------------
  117. # Kiro CLI 配置(agents / settings / steering / skills)
  118. # ---------------------------------------------------------------------------
  119. deploy_kiro() {
  120. info "部署 Kiro CLI 配置到 ${KIRO_HOME}/.kiro ..."
  121. KIRO_RUN_AS_USER="${KIRO_RUN_AS_USER}" KIRO_HOME="${KIRO_HOME}" \
  122. bash "${SCRIPT_DIR}/deploy_kiro_cli.sh"
  123. ok "Kiro CLI 配置部署完成"
  124. }
  125. main() {
  126. local target="${1:-all}"
  127. case "${target}" in
  128. frontend) deploy_frontend ;;
  129. backend) deploy_backend ;;
  130. kiro) deploy_kiro ;;
  131. all) deploy_frontend; deploy_backend; deploy_kiro ;;
  132. *) echo "用法: $0 [all|frontend|backend|kiro]"; exit 1 ;;
  133. esac
  134. echo "===== 部署结束 ====="
  135. }
  136. main "$@"