Files
AI0814_jiaoan_public/student_system_2/DEPLOY.md
T
2026-09-21 17:11:35 +08:00

242 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 学生管理系统 Docker 部署说明
> 本次部署已在你的机器上实际执行并验证通过:
> MySQL、后端、前端三个容器均正常启动,浏览器访问 `http://localhost` 可用。
> 下方命令可直接复制执行。
## 一、部署架构
```
浏览器
│ http://localhost
▼
┌────────────────────────────────┐
│ frontend (node:20 → nginx:1.25) │ 静态文件 /usr/share/nginx/html
└───────────┬────────────────────┘
│ 反向代理(vue/nginx.conf 中已配置)
│ /login /student /files ... → http://backend:9090
▼
┌────────────────────────────────┐
│ backend (python:3.11-slim) │ uvicorn main:app :9090
│ files/ 挂载到宿主机持久化
└───────────┬────────────────────┘
│ aiomysql,DB_HOST=mysql
▼
┌────────────────────────────────┐
│ mysql (mysql:8.0) │ volume: student_mysql_data
│ 库 student_system,启动时自动建表
└────────────────────────────────┘
```
## 二、本次新增的文件
| 文件 | 作用 |
|------|------|
| `student_system_2/docker-compose.yml` | 编排 mysql + backend + frontend 三个服务 |
| `student_system_2/.env` | 实际生效的环境变量(已按你本机端口占用情况配置) |
| `student_system_2/.env.example` | 环境变量模板 |
| `student_system_2/fastapi-app/Dockerfile` | 后端镜像(Python 3.11 + uvicorn,暴露 9090) |
| `student_system_2/fastapi-app/.dockerignore` | 排除 `__pycache__`、虚拟环境等 |
| `student_system_2/vue/Dockerfile` | 前端镜像(Node 20 编译 → Nginx 托管) |
| `student_system_2/vue/.dockerignore` | 排除 `node_modules`、`dist`(关键:否则构建极慢) |
> `vue/nginx.conf` 是原有文件,直接复用,未做修改。其中代理目标写死为 `http://backend:9090`,
> 因此 compose 中后端服务名保持为 `backend`(已一致)。
**镜像地址与端口**
| 服务 | 镜像 | 容器名 | 宿主机端口 |
|------|------|--------|-----------|
| mysql | `mysql:8.0` | `student_system_2-mysql-1` | 13306 → 3306 |
| backend | `student-system-backend:latest` | `student_system_2-backend-1` | 9090 |
| frontend | `student-system-frontend:latest` | `student_system_2-frontend-1` | 80 |
## 三、环境准备
1. 安装 Docker Desktop(Windows/macOS)或 Docker Engine + Compose 插件(Linux)。
2. 验证:
```bash
docker --version
docker compose version
```
当前机器已确认:Docker 28.5.1 / Compose v2.40.2。
## 四、启动
在 `student_system_2` 目录(与 `docker-compose.yml` 同级)执行:
```bash
docker compose up -d --build
```
**启动顺序**由 `depends_on` 控制:MySQL 健康检查通过 → 启动 backend → 启动 frontend。
后端启动时自动建表(代码中 `generate_schemas=True`),无需手动执行迁移,已实测生成
`admin / clazz / course / grade / major / notice / student / student_course` 八张表。
查看状态:
```bash
docker compose ps # 等待 backend、mysql 显示 (healthy)
docker compose logs -f # Ctrl+C 退出,不影响容器运行
```
## 五、访问与验证
| 地址 | 说明 |
|------|------|
| http://localhost | 前端页面(登录/注册) |
| http://localhost:9090/docs | 后端 Swagger 文档 |
| http://localhost:9090/ | 后端根路径 |
| localhost:13306 | MySQL(Navicat/DBeaver 可连,root / 123456) |
## 六、日常运维命令
```bash
# 停止容器(保留数据)
docker compose stop
# 停止并删除容器与网络(数据卷保留,MySQL 数据不丢)
docker compose down
# 改完代码后重新构建并启动
docker compose up -d --build
# 只重启某个服务
docker compose restart backend
# 查看日志
docker compose logs -f backend
# 进入后端容器
docker compose exec backend bash
# 进入 MySQL 命令行
docker compose exec mysql mysql -uroot -p123456
# 查看资源占用
docker stats
```
> 说明:compose 未固定 `container_name`,容器名带项目前缀(`student_system_2-xxx-1`)。
> 因此请使用 `docker compose exec <服务名>` 而不是 `docker exec <容器名>`,更稳妥。
## 七、端口配置
你本机的 **3306 已被本地 MySQL 占用**(PID 6724),因此 `.env` 中已把容器内 3306 映射到宿主机 **13306**:
```ini
# student_system_2/.env
DB_NAME=student_system
DB_USER=root
DB_PASSWORD=123456
MYSQL_HOST_PORT=13306 # 容器内 3306 → 宿主机 13306
BACKEND_HOST_PORT=9090
FRONTEND_HOST_PORT=80 # 浏览器访问 http://localhost
```
修改端口后重新执行 `docker compose up -d` 即可生效。
## 八、数据持久化与备份
| 数据 | 位置 | 说明 |
|------|------|------|
| MySQL 数据 | Docker volume `student_mysql_data` | 删除容器不丢,`docker compose down -v` 才会清除 |
| 上传的文件 | 宿主机 `fastapi-app/files/` | 与容器 `/app/files` 双向同步 |
```bash
# 备份数据库到当前目录
docker compose exec -T mysql mysqldump -uroot -p123456 student_system > backup.sql
# 从备份恢复
docker compose exec -T mysql mysql -uroot -p123456 student_system < backup.sql
# 查看数据卷明细
docker volume inspect student_mysql_data
```
## 九、旧部署遗留容器与数据迁移(重要)
你机器上还存在 **旧目录名 `student_system` 时期**部署的三个已停止容器,
它们的数据卷是独立保存的,**本次部署没有删除或覆盖它们**:
| 遗留对象 | 说明 |
|---------|------|
| 容器 `student-mysql` / `student-backend` / `student-frontend` | 均已 Exited |
| 卷 `student_system_mysql_data` | 旧 MySQL 数据 |
| 卷 `student_system_upload_files` | 旧上传文件 |
新部署的数据库是**全新的空库**(表结构已自动创建,但无数据)。
**如果不需要旧数据**,可以清理掉这些遗留对象:
```bash
docker rm -f student-mysql student-backend student-frontend
docker volume rm student_system_mysql_data student_system_upload_files
docker rmi student_system-frontend student_system-backend
```
**如果需要把旧数据迁移过来**(旧部署用的同样是 root / 123456):
```bash
# 1) 用旧数据卷启动一个临时 MySQL(端口 13307,避免冲突)
docker run -d --name mysql-old -p 13307:3306 -e MYSQL_ROOT_PASSWORD=123456 ^
-v student_system_mysql_data:/var/lib/mysql mysql:8.0
# 2) 等 30 秒左右待其就绪,导出旧数据
docker exec mysql-old mysqldump -uroot -p123456 student_system > old_data.sql
# 3) 导入到新库
docker compose exec -T mysql mysql -uroot -p123456 student_system < old_data.sql
# 4) 清理临时容器
docker rm -f mysql-old
```
> Windows CMD 下换行符用 `^`;PowerShell 下请写成一行。
## 十、常见问题排查
**1. 前端页面打开报 502 / 接口失败**
- 检查:`docker compose ps`、`docker compose logs backend`
- 确认 `backend` 与 `frontend` 同处 `student-net` 网络(compose 已配置)
- 确认 nginx 代理目标仍为 `http://backend:9090`
**2. 后端日志报 `Can't connect to MySQL server`**
- MySQL 首次初始化较慢,等其变为 `healthy` 后会自动重连;必要时 `docker compose restart backend`
- 确认 `DB_HOST=mysql`(不能写 `localhost`,那是容器自身)
- 确认 `.env` 中 `DB_PASSWORD` 与 `MYSQL_ROOT_PASSWORD` 一致
**3. 后端报 `Unknown database 'student_system'`**
- 只有**首次**创建容器时才执行 `MYSQL_DATABASE` 建库。若数据卷已有旧数据则不会重建:
```bash
docker compose exec mysql mysql -uroot -p123456 -e "CREATE DATABASE IF NOT EXISTS student_system DEFAULT CHARSET utf8mb4;"
```
**4. 端口被占用 `Only one usage of each socket address` / `port is already allocated`**
- 按第七节修改 `.env` 中的端口后重新 `docker compose up -d`
- 查占用:`netstat -ano | findstr :3306`
**5. 前端构建很慢或 `npm ci` 失败**
- 确保 `vue/.dockerignore` 含 `node_modules/`(否则会把本机依赖打进构建上下文)
- 若 `package-lock.json` 与 `package.json` 不匹配,Dockerfile 已自动回退为 `npm install`
- 换源构建:`docker build --build-arg NPM_REGISTRY=https://registry.npmjs.org ./vue`
**6. 上传图片后访问 404**
- 确认宿主机 `fastapi-app/files` 目录存在且可写,映射路径为容器 `/app/files`
**7. pip 安装慢**
- Dockerfile 默认使用清华源,可换源:`docker build --build-arg PIP_INDEX_URL=https://pypi.org/simple ./fastapi-app`
## 十一、生产环境建议
1. **修改默认密码**:务必修改 `.env` 中的 `DB_PASSWORD`,不要用 `123456`。
2. **关闭 SQL 日志**:把 `fastapi-app/settings.py` 中 `"echo": True` 改为 `False`,避免大量 SQL 日志拖慢性能。
3. **不对宿主机暴露数据库**:删除 compose 中 `mysql` 的 `ports` 映射(后端走内部网络即可)。
4. **收敛 CORS**:`main.py` 中 `allow_origins=["*"]` 建议改为实际前端域名。
5. **启用 HTTPS**:在 nginx 中增加 443 监听并配置证书。
6. **限制日志体积**:为各服务增加 `logging.options.max-size` / `max-file`。