install_arm_ubuntu.sh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. #!/bin/bash
  2. # 一键安装脚本 - ARM Ubuntu版本
  3. echo "========================================"
  4. echo " DZXJ DTU 应用一键安装脚本 (ARM Ubuntu) "
  5. echo "========================================"
  6. # 设置颜色输出
  7. RED='\033[0;31m'
  8. GREEN='\033[0;32m'
  9. YELLOW='\033[1;33m'
  10. NC='\033[0m' # No Color
  11. # 检查是否在ARM平台
  12. if [[ $(uname -m) != "aarch64" && $(uname -m) != "armv7l" && $(uname -m) != "armv8l" ]]; then
  13. echo -e "${RED}错误: 此安装脚本仅适用于ARM架构的Ubuntu系统${NC}"
  14. echo -e "当前系统架构: $(uname -m)"
  15. exit 1
  16. fi
  17. # 检查是否是Ubuntu系统
  18. if ! command -v lsb_release &> /dev/null || [[ ! $(lsb_release -i 2>/dev/null) =~ Ubuntu ]]; then
  19. echo -e "${YELLOW}警告: 此脚本针对Ubuntu系统优化,您的系统可能不受完全支持${NC}"
  20. read -p "是否继续安装? (y/n): " -n 1 -r
  21. echo
  22. if [[ ! $REPLY =~ ^[Yy]$ ]]; then
  23. exit 1
  24. fi
  25. fi
  26. # 检查是否为root用户并调整安装目录
  27. if [ "$EUID" -eq 0 ]; then
  28. echo -e "${YELLOW}警告: 正在以root用户运行脚本${NC}"
  29. # 为root用户设置不同的安装目录
  30. INSTALL_DIR="/opt/dzxj_dtu"
  31. echo -e "${GREEN}将使用 /opt/dzxj_dtu 作为安装目录${NC}"
  32. else
  33. INSTALL_DIR="$HOME/dzxj_dtu"
  34. fi
  35. # 创建安装目录
  36. INSTALL_DIR="$HOME/dzxj_dtu"
  37. if [ -d "$INSTALL_DIR" ]; then
  38. echo -e "${YELLOW}警告: 安装目录已存在$INSTALL_DIR${NC}"
  39. echo -e "${GREEN}自动覆盖现有安装目录...${NC}"
  40. rm -rf "$INSTALL_DIR"
  41. fi
  42. mkdir -p "$INSTALL_DIR"
  43. echo -e "${GREEN}创建安装目录: $INSTALL_DIR${NC}"
  44. # 配置apt-get使用阿里源
  45. echo -e "${GREEN}配置apt-get使用阿里源...${NC}"
  46. ARCH=$(dpkg --print-architecture)
  47. CODENAME=$(lsb_release -cs)
  48. # 备份原有源文件
  49. if [ ! -f /etc/apt/sources.list.bak ]; then
  50. sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
  51. echo -e "${GREEN}已备份原有源文件到 /etc/apt/sources.list.bak${NC}"
  52. fi
  53. # 配置阿里源
  54. echo -e "${GREEN}设置阿里源...${NC}"
  55. sudo tee /etc/apt/sources.list > /dev/null << EOF
  56. deb http://mirrors.aliyun.com/ubuntu-ports/ $CODENAME main restricted universe multiverse
  57. deb-src http://mirrors.aliyun.com/ubuntu-ports/ $CODENAME main restricted universe multiverse
  58. deb http://mirrors.aliyun.com/ubuntu-ports/ $CODENAME-security main restricted universe multiverse
  59. deb-src http://mirrors.aliyun.com/ubuntu-ports/ $CODENAME-security main restricted universe multiverse
  60. deb http://mirrors.aliyun.com/ubuntu-ports/ $CODENAME-updates main restricted universe multiverse
  61. deb-src http://mirrors.aliyun.com/ubuntu-ports/ $CODENAME-updates main restricted universe multiverse
  62. deb http://mirrors.aliyun.com/ubuntu-ports/ $CODENAME-backports main restricted universe multiverse
  63. deb-src http://mirrors.aliyun.com/ubuntu-ports/ $CODENAME-backports main restricted universe multiverse
  64. EOF
  65. # 安装系统依赖
  66. echo -e "${GREEN}安装系统依赖...${NC}"
  67. sudo apt-get update
  68. # 检查并安装nginx
  69. echo -e "${GREEN}检查nginx安装状态...${NC}"
  70. if ! command -v nginx &> /dev/null; then
  71. echo -e "${YELLOW}nginx未安装,正在安装...${NC}"
  72. sudo apt-get install -y nginx
  73. if [ $? -eq 0 ]; then
  74. echo -e "${GREEN}nginx安装成功${NC}"
  75. else
  76. echo -e "${RED}错误: nginx安装失败${NC}"
  77. exit 1
  78. fi
  79. else
  80. echo -e "${GREEN}nginx已安装${NC}"
  81. fi
  82. # 安装其他依赖
  83. sudo apt-get install -y --no-install-recommends \
  84. python3 python3-venv python3-pip python3-dev \
  85. gcc libffi-dev make \
  86. git curl \
  87. net-tools iproute2 \
  88. mosquitto mosquitto-clients \
  89. libgpiod2 libgpiod-dev
  90. if [ $? -ne 0 ]; then
  91. echo -e "${RED}错误: 系统依赖安装失败${NC}"
  92. exit 1
  93. fi
  94. # 设置npm镜像源为阿里源以加速(如果需要在目标机器上构建)
  95. # echo -e "${GREEN}配置npm镜像源...${NC}"
  96. # npm config set registry https://registry.npmmirror.com --global
  97. # 复制项目文件到安装目录
  98. echo -e "${GREEN}复制项目文件...${NC}"
  99. cp -r "$(pwd)/backend" "$INSTALL_DIR/"
  100. # 复制前端预编译的dist目录
  101. echo -e "${GREEN}复制前端预编译文件...${NC}"
  102. mkdir -p "$INSTALL_DIR/frontend"
  103. # 检查是否存在dist目录
  104. if [ -d "$(pwd)/frontend/dist" ]; then
  105. cp -r "$(pwd)/frontend/dist" "$INSTALL_DIR/frontend/" || echo -e "${YELLOW}警告: 复制frontend/dist失败${NC}"
  106. echo -e "${GREEN}已复制前端预编译文件到 $INSTALL_DIR/frontend/dist${NC}"
  107. else
  108. echo -e "${YELLOW}警告: 未找到前端预编译的dist目录${NC}"
  109. echo -e "${YELLOW}请先在本地执行 npm install && npm run build 构建前端${NC}"
  110. fi
  111. # 创建Python虚拟环境
  112. echo -e "${GREEN}创建Python虚拟环境...${NC}"
  113. python3 -m venv "$INSTALL_DIR/venv"
  114. # 激活虚拟环境
  115. source "$INSTALL_DIR/venv/bin/activate"
  116. # 升级pip并设置镜像源
  117. pip install --upgrade pip
  118. pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
  119. # 安装Python依赖
  120. echo -e "${GREEN}安装Python依赖...${NC}"
  121. pip install --no-cache-dir -r "$INSTALL_DIR/backend/requirements.txt"
  122. if [ $? -ne 0 ]; then
  123. echo -e "${RED}错误: Python依赖安装失败${NC}"
  124. exit 1
  125. fi
  126. # 配置nginx部署前端
  127. echo -e "${GREEN}配置nginx部署前端...${NC}"
  128. # 创建nginx配置文件
  129. NGINX_CONF="dzxj_dtu.conf"
  130. sudo tee "/etc/nginx/sites-available/$NGINX_CONF" > /dev/null << EOF
  131. server {
  132. listen 80;
  133. server_name localhost;
  134. # 前端静态文件目录
  135. root $INSTALL_DIR/frontend/dist;
  136. index index.html;
  137. location / {
  138. try_files \$uri \$uri/ /index.html;
  139. }
  140. # 代理后端API请求
  141. location /api {
  142. proxy_pass http://localhost:5001/api;
  143. proxy_set_header Host \$host;
  144. proxy_set_header X-Real-IP \$remote_addr;
  145. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  146. proxy_set_header X-Forwarded-Proto \$scheme;
  147. }
  148. # WebSocket连接代理
  149. location /socket.io {
  150. proxy_pass http://localhost:5001/socket.io;
  151. proxy_http_version 1.1;
  152. proxy_set_header Upgrade \$http_upgrade;
  153. proxy_set_header Connection 'upgrade';
  154. proxy_set_header Host \$host;
  155. proxy_cache_bypass \$http_upgrade;
  156. }
  157. }
  158. EOF
  159. # 启用nginx配置
  160. if [ -f /etc/nginx/sites-enabled/default ]; then
  161. sudo rm /etc/nginx/sites-enabled/default
  162. echo -e "${GREEN}已移除默认nginx配置${NC}"
  163. fi
  164. sudo ln -sf /etc/nginx/sites-available/$NGINX_CONF /etc/nginx/sites-enabled/
  165. echo -e "${GREEN}已启用nginx配置: $NGINX_CONF${NC}"
  166. # 测试nginx配置并重启
  167. sudo nginx -t
  168. if [ $? -eq 0 ]; then
  169. sudo systemctl restart nginx
  170. echo -e "${GREEN}nginx服务已重启,前端部署成功${NC}"
  171. else
  172. echo -e "${RED}错误: nginx配置有误,请检查${NC}"
  173. fi
  174. # 编译 DHT11 C 读取器(如源码存在)
  175. if [ -f "$INSTALL_DIR/backend/scripts/dht11_reader.c" ]; then
  176. echo -e "${GREEN}编译 DHT11 C 读取器...${NC}"
  177. if command -v gcc >/dev/null 2>&1 && ldconfig -p | grep -q libgpiod; then
  178. gcc -O2 -o "$INSTALL_DIR/backend/scripts/dht11_reader" "$INSTALL_DIR/backend/scripts/dht11_reader.c" -lgpiod
  179. if [ $? -eq 0 ]; then
  180. echo -e "${GREEN}DHT11 C 读取器编译成功${NC}"
  181. else
  182. echo -e "${YELLOW}警告: DHT11 C 读取器编译失败,将回退到 Python gpiod${NC}"
  183. fi
  184. else
  185. echo -e "${YELLOW}警告: 缺少 gcc 或 libgpiod,跳过 DHT11 C 读取器编译${NC}"
  186. fi
  187. fi
  188. # 创建默认环境配置文件(供 systemd EnvironmentFile 使用)
  189. if [ ! -f "/etc/default/dzxj_dtu" ]; then
  190. echo -e "${GREEN}创建默认环境配置文件 /etc/default/dzxj_dtu...${NC}"
  191. cat > /etc/default/dzxj_dtu << 'EOF'
  192. DHT11_ENABLED=true
  193. DHT11_GPIO_PIN=19
  194. DHT11_GPIO_CHIP=gpiochip0
  195. DHT11_POLL_INTERVAL=5
  196. DHT11_SIMULATE=false
  197. EOF
  198. chmod 644 /etc/default/dzxj_dtu
  199. fi
  200. # 创建启动脚本
  201. echo -e "${GREEN}创建启动脚本...${NC}"
  202. cat > "$INSTALL_DIR/start.sh" << 'EOF'
  203. #!/bin/bash
  204. # 启动脚本
  205. RED='\033[0;31m'
  206. GREEN='\033[0;32m'
  207. NC='\033[0m'
  208. echo -e "${GREEN}启动DZXJ DTU应用...${NC}"
  209. # 确保脚本在正确的目录下执行
  210. cd "$(dirname "$0")"
  211. # 激活虚拟环境
  212. source "venv/bin/activate"
  213. # 加载环境变量
  214. export TZ=Asia/Shanghai
  215. if [ -f /etc/default/dzxj_dtu ]; then
  216. set -a
  217. source /etc/default/dzxj_dtu
  218. set +a
  219. fi
  220. # 进入后端目录
  221. cd backend
  222. # 检查端口是否已被占用
  223. if lsof -Pi :5001 -sTCP:LISTEN -t >/dev/null ; then
  224. echo -e "${YELLOW}警告: 端口5001已被占用${NC}"
  225. read -p "是否继续启动? (y/n): " -n 1 -r
  226. echo
  227. if [[ ! $REPLY =~ ^[Yy]$ ]]; then
  228. exit 1
  229. fi
  230. fi
  231. echo -e "${GREEN}应用启动中,访问地址: http://localhost:5001${NC}"
  232. # 启动应用(直接运行 app.py,避免 flask run 与环境变量不兼容的问题)
  233. python app.py
  234. EOF
  235. # 创建停止脚本
  236. echo -e "${GREEN}创建停止脚本...${NC}"
  237. cat > "$INSTALL_DIR/stop.sh" << 'EOF'
  238. #!/bin/bash
  239. # 停止脚本
  240. RED='\033[0;31m'
  241. GREEN='\033[0;32m'
  242. NC='\033[0m'
  243. echo -e "${GREEN}停止DZXJ DTU应用...${NC}"
  244. # 查找并停止应用进程
  245. PIDS=$(lsof -Pi :5001 -sTCP:LISTEN -t)
  246. if [ -n "$PIDS" ]; then
  247. echo -e "${GREEN}停止进程: $PIDS${NC}"
  248. kill -15 $PIDS
  249. # 等待进程停止
  250. for pid in $PIDS; do
  251. echo -e "${GREEN}等待进程 $pid 停止...${NC}"
  252. wait $pid 2>/dev/null
  253. done
  254. echo -e "${GREEN}应用已停止${NC}"
  255. else
  256. echo -e "${YELLOW}没有发现运行中的DZXJ DTU应用${NC}"
  257. fi
  258. EOF
  259. # 创建systemd服务配置(可选)
  260. echo -e "${GREEN}创建systemd服务配置...${NC}"
  261. # 根据运行用户设置适当的配置
  262. if [ "$EUID" -eq 0 ]; then
  263. # root用户的服务配置
  264. cat > "$INSTALL_DIR/dzxj_dtu.service" << EOF
  265. [Unit]
  266. Description=DZXJ DTU Application
  267. After=network.target
  268. [Service]
  269. User=root
  270. WorkingDirectory=$INSTALL_DIR/backend
  271. Environment="TZ=Asia/Shanghai"
  272. EnvironmentFile=-/etc/default/dzxj_dtu
  273. ExecStart=$INSTALL_DIR/venv/bin/python app.py
  274. Restart=on-failure
  275. RestartSec=5
  276. [Install]
  277. WantedBy=multi-user.target
  278. EOF
  279. else
  280. # 普通用户的服务配置
  281. cat > "$INSTALL_DIR/dzxj_dtu.service" << EOF
  282. [Unit]
  283. Description=DZXJ DTU Application
  284. After=network.target
  285. [Service]
  286. User=$USER
  287. WorkingDirectory=$INSTALL_DIR/backend
  288. Environment="TZ=Asia/Shanghai"
  289. EnvironmentFile=-/etc/default/dzxj_dtu
  290. ExecStart=$INSTALL_DIR/venv/bin/python app.py
  291. Restart=on-failure
  292. RestartSec=5
  293. [Install]
  294. WantedBy=multi-user.target
  295. EOF
  296. fi
  297. # 设置脚本执行权限
  298. chmod +x "$INSTALL_DIR/start.sh"
  299. chmod +x "$INSTALL_DIR/stop.sh"
  300. # 配置开机自启动
  301. echo -e "${GREEN}配置开机自启动...${NC}"
  302. # 复制service文件到systemd目录
  303. sudo cp "$INSTALL_DIR/dzxj_dtu.service" /etc/systemd/system/
  304. if [ $? -eq 0 ]; then
  305. echo -e "${GREEN}已复制服务配置到 /etc/systemd/system/dzxj_dtu.service${NC}"
  306. # 重新加载systemd配置
  307. sudo systemctl daemon-reload
  308. if [ $? -eq 0 ]; then
  309. echo -e "${GREEN}已重新加载systemd配置${NC}"
  310. # 启用服务
  311. sudo systemctl enable dzxj_dtu.service
  312. if [ $? -eq 0 ]; then
  313. echo -e "${GREEN}已启用dzxj_dtu服务开机自启动${NC}"
  314. # 启动服务
  315. sudo systemctl start dzxj_dtu.service
  316. if [ $? -eq 0 ]; then
  317. echo -e "${GREEN}dzxj_dtu服务已启动${NC}"
  318. else
  319. echo -e "${YELLOW}警告: dzxj_dtu服务启动失败,请手动检查${NC}"
  320. fi
  321. else
  322. echo -e "${RED}错误: 启用dzxj_dtu服务失败${NC}"
  323. fi
  324. else
  325. echo -e "${RED}错误: 重新加载systemd配置失败${NC}"
  326. fi
  327. else
  328. echo -e "${RED}错误: 复制服务配置失败${NC}"
  329. fi
  330. # 显示安装完成信息
  331. echo -e "\n${GREEN}========================================${NC}"
  332. echo -e "${GREEN} DZXJ DTU 应用安装完成! ${NC}"
  333. echo -e "${GREEN}========================================${NC}\n"
  334. echo -e "安装目录: ${GREEN}$INSTALL_DIR${NC}"
  335. echo -e "\n使用方法:"
  336. echo -e " 1. 手动启动应用:"
  337. echo -e " ${YELLOW}cd $INSTALL_DIR && ./start.sh${NC}"
  338. echo -e "\n 2. 停止应用:"
  339. echo -e " ${YELLOW}cd $INSTALL_DIR && ./stop.sh${NC}"
  340. echo -e "\n 3. 管理系统服务:"
  341. echo -e " ${YELLOW}# 查看服务状态"
  342. echo -e " sudo systemctl status dzxj_dtu.service"
  343. echo -e " # 重启服务"
  344. echo -e " sudo systemctl restart dzxj_dtu.service"
  345. echo -e " # 禁用自启动"
  346. echo -e " sudo systemctl disable dzxj_dtu.service${NC}"
  347. echo -e "\n 4. 检查nginx状态:"
  348. echo -e " ${YELLOW}sudo systemctl status nginx${NC}"
  349. echo -e "\n应用访问地址: ${GREEN}http://localhost${NC}"
  350. echo -e "\n${GREEN}安装成功!${NC}"