server-deploy.sh 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. #!/bin/bash
  2. # ============================================
  3. # 灵越智报 2.0 - 服务器一键部署脚本
  4. # 适用于: Ubuntu 22.04 LTS
  5. # 服务器: lanaipc
  6. # ============================================
  7. set -e
  8. # 颜色定义
  9. RED='\033[0;31m'
  10. GREEN='\033[0;32m'
  11. YELLOW='\033[1;33m'
  12. BLUE='\033[0;34m'
  13. NC='\033[0m'
  14. # 配置
  15. PROJECT_DIR="/mnt/win_home/lingyue-zhibao"
  16. LOG_DIR="/var/log/lingyue"
  17. DATA_DIR="/mnt/win_home/lingyue-data"
  18. # 数据库配置
  19. DB_NAME="lingyue_zhibao"
  20. DB_USER="lingyue"
  21. DB_PASS="123123"
  22. # RabbitMQ 配置
  23. MQ_USER="admin"
  24. MQ_PASS="admin123"
  25. log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
  26. log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
  27. log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
  28. log_title() { echo -e "\n${BLUE}========== $1 ==========${NC}\n"; }
  29. # 检查 root 权限
  30. check_root() {
  31. if [ "$EUID" -ne 0 ]; then
  32. log_error "请使用 root 用户运行此脚本"
  33. exit 1
  34. fi
  35. }
  36. # 安装基础依赖
  37. install_dependencies() {
  38. log_title "安装基础依赖"
  39. apt update
  40. apt install -y openjdk-17-jdk maven git curl wget
  41. log_info "Java 版本: $(java -version 2>&1 | head -1)"
  42. log_info "Maven 版本: $(mvn -version 2>&1 | head -1)"
  43. }
  44. # 安装 PostgreSQL + pgvector
  45. install_postgresql() {
  46. log_title "安装 PostgreSQL + pgvector"
  47. # 安装 PostgreSQL
  48. apt install -y postgresql postgresql-contrib postgresql-server-dev-all build-essential
  49. # 编译安装 pgvector
  50. if [ ! -d "/tmp/pgvector" ]; then
  51. cd /tmp
  52. git clone https://github.com/pgvector/pgvector.git
  53. fi
  54. cd /tmp/pgvector
  55. make clean || true
  56. make
  57. make install
  58. # 启动服务
  59. systemctl enable postgresql
  60. systemctl restart postgresql
  61. log_info "PostgreSQL 已安装并启动"
  62. }
  63. # 配置数据库
  64. setup_database() {
  65. log_title "配置数据库"
  66. # 创建用户和数据库
  67. sudo -u postgres psql <<EOF
  68. DO \$\$
  69. BEGIN
  70. IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '${DB_USER}') THEN
  71. CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASS}';
  72. END IF;
  73. END
  74. \$\$;
  75. SELECT 'CREATE DATABASE ${DB_NAME} OWNER ${DB_USER}'
  76. WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${DB_NAME}')\gexec
  77. GRANT ALL PRIVILEGES ON DATABASE ${DB_NAME} TO ${DB_USER};
  78. EOF
  79. # 创建扩展
  80. sudo -u postgres psql -d ${DB_NAME} <<EOF
  81. CREATE EXTENSION IF NOT EXISTS vector;
  82. CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
  83. EOF
  84. log_info "数据库 ${DB_NAME} 配置完成"
  85. }
  86. # 安装 Redis
  87. install_redis() {
  88. log_title "安装 Redis"
  89. apt install -y redis-server
  90. systemctl enable redis-server
  91. systemctl restart redis-server
  92. log_info "Redis 已安装: $(redis-cli ping)"
  93. }
  94. # 安装 RabbitMQ
  95. install_rabbitmq() {
  96. log_title "安装 RabbitMQ"
  97. apt install -y rabbitmq-server
  98. systemctl enable rabbitmq-server
  99. systemctl restart rabbitmq-server
  100. # 启用管理插件
  101. rabbitmq-plugins enable rabbitmq_management
  102. # 创建用户
  103. rabbitmqctl add_user ${MQ_USER} ${MQ_PASS} 2>/dev/null || true
  104. rabbitmqctl set_user_tags ${MQ_USER} administrator
  105. rabbitmqctl set_permissions -p / ${MQ_USER} ".*" ".*" ".*"
  106. log_info "RabbitMQ 已安装,管理界面: http://localhost:15672"
  107. }
  108. # 安装 Ollama
  109. install_ollama() {
  110. log_title "安装 Ollama"
  111. if ! command -v ollama &> /dev/null; then
  112. curl -fsSL https://ollama.ai/install.sh | sh
  113. fi
  114. # 启动 Ollama
  115. nohup ollama serve > /var/log/ollama.log 2>&1 &
  116. sleep 5
  117. # 下载 Embedding 模型
  118. if ! ollama list | grep -q "nomic-embed-text"; then
  119. log_info "下载 nomic-embed-text 模型..."
  120. ollama pull nomic-embed-text
  121. fi
  122. log_info "Ollama 已安装"
  123. }
  124. # 部署项目
  125. deploy_project() {
  126. log_title "部署项目"
  127. # 创建目录
  128. mkdir -p ${LOG_DIR}
  129. mkdir -p ${DATA_DIR}
  130. # 进入项目目录
  131. if [ ! -d "${PROJECT_DIR}" ]; then
  132. log_error "项目目录不存在: ${PROJECT_DIR}"
  133. log_info "请先克隆项目到 ${PROJECT_DIR}"
  134. exit 1
  135. fi
  136. cd ${PROJECT_DIR}
  137. # 初始化数据库表
  138. log_info "初始化数据库表..."
  139. PGPASSWORD=${DB_PASS} psql -U ${DB_USER} -d ${DB_NAME} -h localhost -f backend/sql/init.sql
  140. PGPASSWORD=${DB_PASS} psql -U ${DB_USER} -d ${DB_NAME} -h localhost -f backend/sql/rag_tables.sql 2>/dev/null || true
  141. # 编译项目
  142. log_info "编译项目..."
  143. cd backend
  144. mvn clean package -DskipTests -q
  145. log_info "项目编译完成"
  146. }
  147. # 创建 Systemd 服务
  148. create_systemd_service() {
  149. log_title "创建 Systemd 服务"
  150. cat > /etc/systemd/system/lingyue.service <<EOF
  151. [Unit]
  152. Description=Lingyue Zhibao Application
  153. After=network.target postgresql.service redis-server.service rabbitmq-server.service
  154. [Service]
  155. Type=simple
  156. User=root
  157. WorkingDirectory=${PROJECT_DIR}/backend
  158. ExecStart=/usr/bin/java -Xms1g -Xmx2g -XX:+UseG1GC -jar lingyue-starter/target/lingyue-starter.jar
  159. Restart=always
  160. RestartSec=10
  161. StandardOutput=append:${LOG_DIR}/lingyue.log
  162. StandardError=append:${LOG_DIR}/lingyue-error.log
  163. Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
  164. Environment=SPRING_PROFILES_ACTIVE=prod
  165. [Install]
  166. WantedBy=multi-user.target
  167. EOF
  168. systemctl daemon-reload
  169. log_info "Systemd 服务已创建"
  170. }
  171. # 启动应用
  172. start_app() {
  173. log_title "启动应用"
  174. systemctl enable lingyue
  175. systemctl restart lingyue
  176. sleep 10
  177. if systemctl is-active --quiet lingyue; then
  178. log_info "应用启动成功"
  179. log_info "访问地址: http://$(hostname -I | awk '{print $1}'):8000"
  180. else
  181. log_error "应用启动失败,查看日志: journalctl -u lingyue -f"
  182. fi
  183. }
  184. # 停止应用
  185. stop_app() {
  186. log_title "停止应用"
  187. systemctl stop lingyue
  188. log_info "应用已停止"
  189. }
  190. # 查看状态
  191. show_status() {
  192. log_title "服务状态"
  193. echo "PostgreSQL: $(systemctl is-active postgresql)"
  194. echo "Redis: $(systemctl is-active redis-server)"
  195. echo "RabbitMQ: $(systemctl is-active rabbitmq-server)"
  196. echo "Lingyue: $(systemctl is-active lingyue)"
  197. if command -v ollama &> /dev/null && curl -s http://localhost:11434/api/tags > /dev/null 2>&1; then
  198. echo "Ollama: running"
  199. else
  200. echo "Ollama: stopped"
  201. fi
  202. echo ""
  203. if systemctl is-active --quiet lingyue; then
  204. log_info "应用访问地址: http://$(hostname -I | awk '{print $1}'):8000"
  205. fi
  206. }
  207. # 查看日志
  208. show_logs() {
  209. journalctl -u lingyue -f
  210. }
  211. # 健康检查
  212. health_check() {
  213. log_title "健康检查"
  214. local health=$(curl -s http://localhost:8000/actuator/health 2>/dev/null)
  215. if [ -n "$health" ]; then
  216. echo "$health" | python3 -m json.tool 2>/dev/null || echo "$health"
  217. else
  218. log_error "应用未响应"
  219. fi
  220. }
  221. # 完整安装
  222. full_install() {
  223. check_root
  224. install_dependencies
  225. install_postgresql
  226. setup_database
  227. install_redis
  228. install_rabbitmq
  229. install_ollama
  230. deploy_project
  231. create_systemd_service
  232. start_app
  233. log_title "部署完成"
  234. show_status
  235. }
  236. # 仅更新代码
  237. update_only() {
  238. log_title "更新代码"
  239. cd ${PROJECT_DIR}
  240. git pull origin main || git pull origin master || true
  241. cd backend
  242. mvn clean package -DskipTests -q
  243. systemctl restart lingyue
  244. sleep 10
  245. health_check
  246. }
  247. # 显示帮助
  248. show_help() {
  249. cat <<EOF
  250. 灵越智报 2.0 - 服务器部署脚本
  251. 用法: ./server-deploy.sh [命令]
  252. 命令:
  253. install 完整安装(首次部署)
  254. update 仅更新代码并重启
  255. start 启动应用
  256. stop 停止应用
  257. restart 重启应用
  258. status 查看服务状态
  259. logs 查看应用日志
  260. health 健康检查
  261. help 显示此帮助
  262. 首次部署:
  263. ./server-deploy.sh install
  264. 更新部署:
  265. ./server-deploy.sh update
  266. EOF
  267. }
  268. # 主函数
  269. main() {
  270. case "${1:-help}" in
  271. install)
  272. full_install
  273. ;;
  274. update)
  275. update_only
  276. ;;
  277. start)
  278. start_app
  279. ;;
  280. stop)
  281. stop_app
  282. ;;
  283. restart)
  284. systemctl restart lingyue
  285. sleep 5
  286. health_check
  287. ;;
  288. status)
  289. show_status
  290. ;;
  291. logs)
  292. show_logs
  293. ;;
  294. health)
  295. health_check
  296. ;;
  297. help|--help|-h)
  298. show_help
  299. ;;
  300. *)
  301. log_error "未知命令: $1"
  302. show_help
  303. exit 1
  304. ;;
  305. esac
  306. }
  307. main "$@"