# Ubuntu 零 Node 部署文档 > **中学成绩档案系统** · 版权所有 © 马建军 · 微信 **dekun03** · 手机 **18364911125** > 仓库:[https://git.bz121.com/dekun/secondary-school-grade-archive.git](https://git.bz121.com/dekun/secondary-school-grade-archive.git) --- ## 1. 部署方式 | 项目 | 说明 | |------|------| | 方式 | **systemd + FastAPI 单进程**(服务器**无需** Node.js / npm) | | 系统 | Ubuntu 20.04 / 22.04 / 24.04 | | 用户 | **root** | | 目录 | `/opt/secondary-school-grade-archive` | | 端口 | **23566**(API + 前端静态资源同一端口) | ### 架构 ``` 浏览器 → :23566 (systemd: grade-archive, Uvicorn) ├── /api/* → FastAPI 接口 └── /* → frontend/dist 静态文件 └──→ PostgreSQL (本机) └──→ uploads/ └──→ Ollama (本机可选, :11434) ``` ### 为何不在服务器构建前端? 前端 `npm ci && npm run build` 会占用大量磁盘与内存,且需在服务器安装 Node.js。 因此采用 **开发机构建 → 推送 `frontend/dist` → 服务器只拉取** 的方式,服务器仅需 Python + PostgreSQL。 --- ## 2. 代码修改与发布流程(重要) 每次修改代码后,按改动范围在**开发机**操作,再推送到远端仓库,最后在服务器执行 `update.sh`。 > **服务器需代理时**:在 `update.sh` 前设置与 [§3 一键部署](#3-一键部署新服务器) 相同的 `export http_proxy=...` 命令。 ### 流程总览 ``` ┌─────────────┐ ┌──────────────────┐ ┌─────────────┐ ┌─────────────────┐ │ 开发机改代码 │ → │ 本地构建(如需) │ → │ git push 远端 │ → │ 服务器 update.sh │ └─────────────┘ └──────────────────┘ └─────────────┘ └─────────────────┘ ``` ### 2.1 仅修改后端(`backend/`) 不涉及前端页面时,**无需** `npm run build`: ```bash git add backend/ git commit -m "fix: 说明本次改动" git push ``` 服务器: ```bash bash /opt/secondary-school-grade-archive/deploy/update.sh ``` `update.sh` 会:`git pull` → `pip install` → `systemctl restart grade-archive`。 ### 2.2 修改前端(`frontend/src` 等)或同时改前后端 **必须先在开发机构建**,并将构建产物 `frontend/dist/` 提交到仓库: ```powershell # Windows .\deploy\build-frontend.ps1 ``` ```bash # Linux / macOS bash deploy/build-frontend.sh ``` 上述脚本等价于 `cd frontend && npm ci && npm run build`,并检查 `dist/index.html` 是否生成。 然后提交并推送(**务必包含 `frontend/dist`**): ```bash git add frontend/ frontend/dist git commit -m "feat: 说明本次改动" git push ``` 服务器: ```bash bash /opt/secondary-school-grade-archive/deploy/update.sh ``` ### 2.3 常见错误 | 现象 | 原因 | 处理 | |------|------|------| | 服务器页面没变化 | 只 push 了源码,未 push `frontend/dist` | 本地 `npm run build` 后重新提交 dist | | `install.sh` 报错找不到 dist | 仓库里没有预构建的 dist | 开发机构建并 push 后再部署 | | API 正常但页面 404 | `FRONTEND_DIST` 路径不对 | 检查 `.env` 中 `FRONTEND_DIST` | --- ## 3. 一键部署(新服务器) 若服务器访问 Git / apt / PyPI 需走代理,**在 `bash deploy/install.sh` 之前**设置: ```bash export http_proxy=http://192.168.8.246:10810 export https_proxy=http://192.168.8.246:10810 export HTTP_PROXY="$http_proxy" export HTTPS_PROXY="$https_proxy" ``` 完整安装命令: ```bash git clone https://git.bz121.com/dekun/secondary-school-grade-archive.git /opt/secondary-school-grade-archive cd /opt/secondary-school-grade-archive chmod +x deploy/*.sh bash deploy/install.sh ``` > 脚本会读取上述环境变量,并自动配置 `apt` 代理。`git pull`、`pip install` 同样生效。内网直连时可不设代理。 脚本自动完成: 1. 安装 PostgreSQL、Python 依赖 2. 检查 `frontend/dist/index.html` 是否存在 3. 生成 `.env`、创建数据库 4. 注册并启动 systemd 服务 `grade-archive` **前提:** 仓库中已包含 `frontend/dist/`(开发机构建后推送)。 部署成功后访问:**`http://<服务器IP>:23566`** 默认超级管理员:**admin / admin123**(登录后请在「系统设置」中修改) --- ## 4. 环境变量(`.env`) | 变量 | 默认 | 说明 | |------|------|------| | `WEB_PORT` | 23566 | 对外端口 | | `FRONTEND_DIST` | `.../frontend/dist` | 前端静态目录(绝对路径) | | `DATABASE_URL` | 自动生成 | PostgreSQL 连接 | | `SECRET_KEY` | 自动生成 | JWT 密钥 | | `UPLOAD_DIR` | `.../uploads` | 错题图片目录 | | `ADMIN_DEFAULT_USERNAME` | admin | 首次安装默认管理员用户名 | | `ADMIN_DEFAULT_PASSWORD` | admin123 | 首次安装默认管理员密码 | 示例见仓库根目录 [.env.example](../.env.example)。 --- ## 5. 常用命令 ```bash # 服务状态 systemctl status grade-archive # 实时日志 journalctl -u grade-archive -f # 拉代码并重启(日常更新;需代理时先 export,见 §3) export http_proxy=http://192.168.8.246:10810 export https_proxy=http://192.168.8.246:10810 export HTTP_PROXY="$http_proxy" export HTTPS_PROXY="$https_proxy" bash /opt/secondary-school-grade-archive/deploy/update.sh # 备份数据库与 uploads bash /opt/secondary-school-grade-archive/deploy/backup.sh ``` --- ## 6. 从旧版 PM2 迁移 若之前使用 `grade-api` + `grade-web`(PM2 + Express),执行 `deploy/update.sh` 会: - 停止并删除 PM2 进程 `grade-api`、`grade-web` - 重启 systemd 服务 `grade-archive` `.env` 调整建议: - 保留 `WEB_PORT=23566` - 添加 `FRONTEND_DIST=/opt/secondary-school-grade-archive/frontend/dist` - 可删除 `API_PORT`、`API_TARGET`(已不再使用) --- ## 7. 超级管理员 | 功能 | 说明 | |------|------| | 默认账号 | **admin / admin123**(首次安装后请立即修改) | | 系统设置 | 超级管理员可修改自己的用户名、密码 | | 注册开关 | 可开启/关闭登录页公开注册 | | 用户管理 | 注册关闭时,由管理员添加用户并重置密码 | | 普通用户 | **不能**自行修改用户名和密码 | 使用说明见 [USAGE.md](./USAGE.md)。 --- ## 8. 反向代理(用户自行配置) 本项目**不包含** Nginx / Caddy 等反向代理配置。若需 HTTPS 或域名访问,请在服务器上自行配置,将流量转发到 `127.0.0.1:23566`。 --- ## 9. OCR 报错 libGL.so.1 若错题识别失败并提示 `libGL.so.1: cannot open shared object file`,说明服务器缺少 OpenGL 运行库(PaddleOCR/OpenCV 需要)。 在服务器执行: ```bash cd /opt/secondary-school-grade-archive git pull sudo bash deploy/install-ocr-deps.sh sudo systemctl restart grade-archive ``` 或执行完整更新(已包含 OCR 依赖检查): ```bash sudo bash deploy/update.sh ``` --- ## 10. 更新后无法访问(连接被拒绝) 若浏览器提示 **ERR_CONNECTION_REFUSED**,通常是 `update.sh` 停止了旧 PM2,但 **systemd 服务未成功启动**。 在服务器执行一键修复: ```bash cd /opt/secondary-school-grade-archive git pull sudo bash deploy/repair.sh ``` 手动排查: ```bash systemctl status grade-archive journalctl -u grade-archive -n 50 --no-pager ss -tlnp | grep 23566 ``` > **注意:** `update.sh` / `repair.sh` 必须用 **root** 运行(`sudo bash ...`)。 --- ## 11. 技术支持 微信 **dekun03** · 手机 **18364911125**