零 Node 部署、超级管理员,并完善本地构建发布文档。

- FastAPI 单进程托管 frontend/dist,systemd 替代 PM2

- 超级管理员 admin、注册开关与用户管理

- README/DEPLOY/USAGE 说明:改代码须本地构建 dist 后 push,服务器 update.sh

- 提交 frontend/dist 与 build-frontend 脚本
This commit is contained in:
dekun
2026-06-28 13:19:41 +08:00
parent a3d4875bde
commit f1ad4273f4
34 changed files with 1567 additions and 268 deletions
+122 -94
View File
@@ -1,4 +1,4 @@
# Ubuntu PM2 部署文档
# Ubuntu 零 Node 部署文档
> **中学成绩档案系统** · 版权所有 © 马建军 · 微信 **dekun03** · 手机 **18364911125**
> 仓库:[https://git.bz121.com/dekun/secondary-school-grade-archive.git](https://git.bz121.com/dekun/secondary-school-grade-archive.git)
@@ -9,41 +9,101 @@
| 项目 | 说明 |
|------|------|
| 方式 | **PM2**(非 Docker |
| 方式 | **systemd + FastAPI 单进程**(服务器**无需** Node.js / npm |
| 系统 | Ubuntu 20.04 / 22.04 / 24.04 |
| 用户 | **root** |
| 目录 | `/opt/secondary-school-grade-archive` |
| 端口 | **23566** 对外 Web**23568** 内部 API(仅本机 |
| 反向代理 | **不包含**,请自行配置 |
| 端口 | **23566**API + 前端静态资源同一端口 |
### 架构
```
浏览器 → :23566 (PM2: grade-web, Express 静态 + /api 反代)
──→ 127.0.0.1:23568 (PM2: grade-api, Uvicorn)
浏览器 → :23566 (systemd: grade-archive, Uvicorn)
── /api/* → FastAPI 接口
└── /* → frontend/dist 静态文件
└──→ PostgreSQL (本机)
└──→ uploads/
└──→ Ollama (本机可选, :11434)
```
PM2 进程:
### 为何不在服务器构建前端?
| 名称 | 说明 |
|------|------|
| `grade-api` | FastAPI / Uvicorn |
| `grade-web` | 前端静态资源 + `/api` 反向代理 |
前端 `npm ci && npm run build` 会占用大量磁盘与内存,且需在服务器安装 Node.js。
因此采用 **开发机构建 → 推送 `frontend/dist` → 服务器只拉取** 的方式,服务器仅需 Python + PostgreSQL。
---
## 2. 环境要求
## 2. 代码修改与发布流程(重要)
- CPU 2 核+,内存 4 GB+OCR 建议 8 GB
- 磁盘 15 GB+
- 可访问 Git 仓库与 npm / PyPI
每次修改代码后,按改动范围在**开发机**操作,再推送到远端仓库,最后在服务器执行 `update.sh`
### 流程总览
```
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐ ┌─────────────────┐
│ 开发机改代码 │ → │ 本地构建(如需) │ → │ 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. 一键部署
## 3. 一键部署(新服务器)
```bash
git clone https://git.bz121.com/dekun/secondary-school-grade-archive.git /opt/secondary-school-grade-archive
@@ -54,120 +114,88 @@ bash deploy/install.sh
脚本自动完成:
1. 检测 root、Ubuntu、端口 23566
2. 安装 PostgreSQL、Python3、Node.js 20、PM2
3. 克隆/更新代码
4. 生成 `.env`(随机密钥、数据库密码)
5. 创建 PostgreSQL 用户与数据库
6. Python 虚拟环境 + `pip install`
7. 前端 `npm ci && npm run build`
8. `pm2 start` 并设置开机自启
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 | 对外 Web 端口 |
| `API_PORT` | 23568 | 内部 API 端口(仅本机,勿与 8000 等常用端口冲突 |
| `API_TARGET` | `http://127.0.0.1:23568` | Web 网关转发目标 |
| `WEB_PORT` | 23566 | 对外端口 |
| `FRONTEND_DIST` | `.../frontend/dist` | 前端静态目录(绝对路径 |
| `DATABASE_URL` | 自动生成 | PostgreSQL 连接 |
| `SECRET_KEY` | 自动生成 | JWT 密钥 |
| `UPLOAD_DIR` | `.../uploads` | 错题图片目录 |
| `OLLAMA_BASE_URL` | `http://127.0.0.1:11434` | 本地 Ollama |
| `ADMIN_DEFAULT_USERNAME` | admin | 首次安装默认管理员用户名 |
| `ADMIN_DEFAULT_PASSWORD` | admin123 | 首次安装默认管理员密码 |
修改后重启:
```bash
cd /opt/secondary-school-grade-archive
pm2 reload deploy/pm2/ecosystem.config.cjs --update-env
```
示例见仓库根目录 [.env.example](../.env.example)。
---
## 5. 常用命令
```bash
cd /opt/secondary-school-grade-archive
# 服务状态
systemctl status grade-archive
pm2 status # 进程状态
pm2 logs # 全部日志
pm2 logs grade-api # 后端日志
pm2 logs grade-web # 网关日志
# 实时日志
journalctl -u grade-archive -f
bash deploy/update.sh # 拉代码 + 重建 + 重启
bash deploy/backup.sh # 备份数据库与 uploads
bash deploy/uninstall.sh # 停止 PM2 服务
# 拉代码并重启(日常更新)
bash /opt/secondary-school-grade-archive/deploy/update.sh
# 备份数据库与 uploads
bash /opt/secondary-school-grade-archive/deploy/backup.sh
```
---
## 6. Ollama(可选)
## 6. 从旧版 PM2 迁移
```bash
curl -fsSL https://ollama.com/install.sh | sh
ollama pull qwen2.5:7b
```
若之前使用 `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. 反向代理(自行配置)
## 7. 超级管理员
将域名/HTTPS 流量转发到 **`http://127.0.0.1:23566`** 即可。
使用 HTTPS 后请更新 `.env``CORS_ORIGINS`
---
## 8. 防火墙
```bash
ufw allow 22/tcp
ufw allow 23566/tcp
ufw enable
```
---
## 9. 故障排查
| 现象 | 处理 |
| 功能 | 说明 |
|------|------|
| 无法访问 | `pm2 status` · `ss -tlnp \| grep 23566` |
| 502 / API 错误 | `pm2 logs grade-api` |
| 数据库连接失败 | `systemctl status postgresql` · 检查 `.env``DATABASE_URL` |
| 前端空白 | 确认 `frontend/dist` 存在 · `pm2 logs grade-web` |
| 默认账号 | **admin / admin123**(首次安装后请立即修改) |
| 系统设置 | 超级管理员可修改自己的用户名、密码 |
| 注册开关 | 可开启/关闭登录页公开注册 |
| 用户管理 | 注册关闭时,由管理员添加用户并重置密码 |
| 普通用户 | **不能**自行修改用户名和密码 |
使用说明见 [USAGE.md](./USAGE.md)。
---
## 10. 自定义参数
## 8. 反向代理(用户自行配置)
```bash
WEB_PORT=23566 INSTALL_DIR=/opt/secondary-school-grade-archive bash deploy/install.sh
# 使用官方 PyPI(海外服务器可去掉国内镜像)
PIP_MIRROR=https://pypi.org/simple bash deploy/install.sh
```
### 网络代理(可选,脚本内不内置)
一键部署**不会**自动配置代理。无代理环境可直接运行,不会因代理报错。
若本机网络需走代理,请在**执行安装前**手动 export(仅当前终端生效):
```bash
export HTTP_PROXY=http://你的代理地址:端口
export HTTPS_PROXY=http://你的代理地址:端口
bash deploy/install.sh
```
不设置则不走代理。`pip install` 会**显示完整下载/安装进度**,不再静默。
本项目**不包含** Nginx / Caddy 等反向代理配置。若需 HTTPS 或域名访问,请在服务器上自行配置,将流量转发到 `127.0.0.1:23566`
---
## 11. 版权
## 9. 技术支持
见 [LICENSE](../LICENSE) · [COPYRIGHT.md](../COPYRIGHT.md)
技术支持:微信 **dekun03** · 手机 **18364911125**
微信 **dekun03** · 手机 **18364911125**
+61 -11
View File
@@ -16,7 +16,7 @@
- 错题库:拍照上传 → OCR 识别 → AI 生成解法(可编辑)
- 成绩 CSV 导出
部署方式见 [DEPLOY.md](./DEPLOY.md)PM2,端口 23566)。
部署与代码发布见 [DEPLOY.md](./DEPLOY.md)systemd 零 Node,端口 **23566**)。
---
@@ -25,12 +25,23 @@
### 2.1 登录与注册
1. 浏览器打开 `http://<服务器IP>:23566`
2. 首次使用点击 **注册**,设置用户名(≥3 字符)和密码(≥6 字符
3. 注册成功后自动登录
2. **首次部署**默认超级管理员:**admin / admin123**(请登录后立即修改
3. 若管理员已**开放注册**,可在登录页 **注册** 新账号(用户名 ≥3 字符,密码 ≥6 字符)
4. 若管理员已**关闭注册**,登录页不显示注册入口,需联系管理员在「系统设置 → 用户管理」中添加账号
> 系统无默认管理员账号,首个注册用户即为普通用户数据仅本人可见。
> 普通用户数据仅本人可见;普通用户**不能**自行修改用户名或密码
### 2.2 添加学生
### 2.2 系统设置(超级管理员)
首页右上角 **系统设置**(仅超级管理员可见):
| 功能 | 说明 |
|------|------|
| 注册开关 | 开启后用户可自行注册;关闭后仅管理员添加用户 |
| 管理员账号 | 修改超级管理员的用户名、密码(修改密码需输入当前密码) |
| 用户管理 | 添加用户、重置密码、删除普通用户 |
### 2.3 添加学生
1. 首页点击 **添加学生**
2. 填写:
@@ -40,7 +51,7 @@
- **班级**:如「3班」(可选)
3. 保存后在卡片上可看到学段标签
### 2.3 录入成绩
### 2.4 录入成绩
进入学生详情 → **成绩录入** 标签:
@@ -130,13 +141,49 @@
---
## 7. 常见问题
## 7. 维护人员:修改代码后如何更新线上
**服务器不在本地构建前端。** 维护或二次开发时,请严格按以下流程发布:
### 只改后端
```bash
git add backend/
git commit -m "说明"
git push
# 服务器
bash /opt/secondary-school-grade-archive/deploy/update.sh
```
### 改前端(或前后端都改)
```powershell
# Windows:先构建
.\deploy\build-frontend.ps1
```
```bash
# Linux / macOS:先构建
bash deploy/build-frontend.sh
git add frontend/ frontend/dist
git commit -m "说明"
git push
# 服务器
bash /opt/secondary-school-grade-archive/deploy/update.sh
```
详细说明见 [DEPLOY.md §2](./DEPLOY.md#2-代码修改与发布流程重要) 与 [README](../README.md#修改代码后如何发布必读)。
---
## 8. 常见问题
**Q:忘记密码怎么办?**
A当前版本无找回密码功能,需管理员在数据库中重置或重新注册(生产环境建议后续增加找回流程)
A普通用户请联系超级管理员,在「系统设置 → 用户管理」中重置密码。超级管理员忘记密码需通过数据库或 `.env` 中的 `ADMIN_DEFAULT_*` 配合运维处理
**Q:多人能否共用一台服务器?**
A:可以。每人注册独立账号,数据互不可见。
A:可以。每人独立账号,数据互不可见。
**Q:能否同时管理初中和高中孩子?**
A:可以。添加学生时分别选择学段即可。
@@ -145,11 +192,14 @@ A:可以。添加学生时分别选择学段即可。
A:可以。使用同一服务器地址与账号登录即可。
**QHTTPS 和域名怎么配置?**
A:本项目不包含反向代理配置,请参考 [DEPLOY.md 第 7 节](./DEPLOY.md#7-反向代理用户自行配置) 自行设置。
A:本项目不包含反向代理配置,请参考 [DEPLOY.md §8](./DEPLOY.md#8-反向代理用户自行配置) 自行设置。
**Q:改了代码但服务器页面没变化?**
A:很可能未在开发机执行 `npm run build` 或未将 `frontend/dist` 推送到仓库。见上文第 7 节。
---
## 8. 技术支持与版权
## 9. 技术支持与版权
| 项目 | 内容 |
|------|------|