224 lines
7.7 KiB
Markdown
224 lines
7.7 KiB
Markdown
# Docker 部署指南
|
||
|
||
## 项目简介
|
||
|
||
仓库物料管理系统 (WMMS) - 前后端分离架构
|
||
|
||
- **后端**: Go + Gin + MySQL (端口 8082)
|
||
- **前端**: Vue 3 + Vite + Nginx (端口 80)
|
||
- **数据库**: MySQL 8.0 (端口 3306)
|
||
|
||
## 快速启动 (Windows)
|
||
|
||
### 前置条件
|
||
|
||
1. 安装 [Docker Desktop](https://www.docker.com/products/docker-desktop/) (Windows 10/11)
|
||
2. 启动 Docker Desktop
|
||
|
||
### 启动服务
|
||
|
||
```bash
|
||
# 进入项目目录
|
||
cd c:\1111\12.project\VSCode\warehouse-mms
|
||
|
||
# 启动所有服务
|
||
docker-compose up -d
|
||
|
||
# 查看服务状态
|
||
docker-compose ps
|
||
```
|
||
|
||
### 访问应用
|
||
|
||
- 前端地址: http://localhost
|
||
- 后端API: http://localhost:8082/api (绑定在 `127.0.0.1`,仅限本机)
|
||
- 健康检查: http://localhost:8082/api/health
|
||
|
||
### 用手机 / 局域网其他设备访问
|
||
|
||
手机连上**与电脑同一个 WiFi**,浏览器打开 `http://<电脑的局域网IP>`,用下节账号登录即可,**不需要带端口号**(80 是 HTTP 的默认端口,浏览器会自动使用)。
|
||
|
||
先查看电脑的局域网 IP —— 取 `WLAN` 那一行的地址,忽略 `vEthernet (WSL)`、`VMware Network Adapter` 这些虚拟网卡:
|
||
|
||
```bash
|
||
ipconfig
|
||
```
|
||
|
||
例如地址是 `192.168.31.76`,手机就访问 `http://192.168.31.76`。
|
||
|
||
**为什么不需要改配置**:前端请求走相对路径 `/api`,手机访问时会自动打到 `http://<电脑IP>/api`,再由 Nginx 反代给后端容器。前后端都没有硬编码 `localhost`,所以换任何 IP 访问都能正常工作。
|
||
|
||
#### 端口绑定策略
|
||
|
||
| 服务 | 绑定地址 | 局域网可访问 | 原因 |
|
||
|------|----------|--------------|------|
|
||
| frontend | `0.0.0.0:80` | ✅ 是 | 手机、其他设备要打开网页 |
|
||
| backend | `127.0.0.1:8082` | ❌ 否 | 前端经 Nginx 走**容器内部网络**反代(`proxy_pass http://backend:8082`),不经过宿主机端口 |
|
||
| db | `127.0.0.1:3307` | ❌ 否 | 数据库不应暴露;本机仍可用客户端连 3307 调试 |
|
||
|
||
后端和数据库绑定在 `127.0.0.1` 是**有意的安全设置**,只允许本机访问。若你临时需要让别的机器直连后端 API 调试,把 `docker-compose.yml` 里对应那行改回 `"8082:8082"`,再执行 `docker compose up -d`(改完记得改回去)。
|
||
|
||
#### 手机打不开时怎么查
|
||
|
||
1. **确认同一个 WiFi**:手机和电脑必须是同一个 SSID。
|
||
2. **WiFi 的客户端隔离(AP 隔离)**:单位、公共场所的网络常开启此功能,导致设备之间无法互访。这属于网络策略,与本项目无关 —— 用手机开热点让电脑连上试一次即可确认。
|
||
3. **Windows 防火墙**:需放行 80 端口入站。Docker Desktop 安装时会按其网络类别自动添加放行规则,若仍不通,用管理员 PowerShell 临时加一条:
|
||
```powershell
|
||
New-NetFirewallRule -DisplayName "WMMS 80" -Direction Inbound -LocalPort 80 -Protocol TCP -Action Allow
|
||
# 测试完删除:Remove-NetFirewallRule -DisplayName "WMMS 80"
|
||
```
|
||
4. **IP 会变**:`192.168.x.x` 由 DHCP 分配,路由器重启后可能变化。想长期使用,建议在路由器上给这台电脑做静态 IP 绑定。
|
||
|
||
> ⚠️ 数据库使用默认密码 `wmms1234`,后端 API 也没有额外的访问控制,因此**不要把 8082 / 3307 暴露到公网**。
|
||
|
||
### 默认用户
|
||
|
||
| 用户名 | 密码 | 角色 |
|
||
|--------|------|------|
|
||
| admin | admin123 | 管理员 |
|
||
| user | user123 | 普通用户 |
|
||
|
||
## 常用命令
|
||
|
||
```bash
|
||
# 查看日志
|
||
docker-compose logs -f
|
||
|
||
# 查看后端日志
|
||
docker-compose logs -f backend
|
||
|
||
# 停止服务
|
||
docker-compose down
|
||
|
||
# 重新构建并启动
|
||
docker-compose up -d --build
|
||
|
||
# 删除所有数据(谨慎操作)
|
||
docker-compose down -v
|
||
```
|
||
|
||
## 数据持久化
|
||
|
||
- **MySQL数据**: `mysql_data` Docker volume
|
||
- **上传文件**: `uploads_data` Docker volume
|
||
|
||
### ⚠️ 数据卷复用会导致表结构落后于代码
|
||
|
||
MySQL 官方镜像**只在数据目录为空时**才执行 `/docker-entrypoint-initdb.d/` 下的脚本。也就是说 `scripts/init.sql` **只在 `mysql_data` 卷第一次创建时执行一次**;只要卷还在,后续 `docker compose up -d` 一律直接复用旧数据,`init.sql` 完全不执行。
|
||
|
||
`docker compose down` **不带 `-v` 时卷会保留**,所以改过 schema 之后重新部署,新代码会跑在旧表结构上。典型症状是**容器全部 healthy、日志干净,但部分接口返回 500**:
|
||
|
||
```
|
||
Error 1054 (42S22): Unknown column 'inbound_no' in 'field list'
|
||
```
|
||
|
||
**部署前先确认现有表结构**:
|
||
|
||
```bash
|
||
docker compose exec db mysql -uroot -pwmms1234 -e "SHOW COLUMNS FROM inbound_orders; SHOW COLUMNS FROM outbound_orders; SHOW COLUMNS FROM material_categories;" wmms
|
||
```
|
||
|
||
将实际字段与当前 `scripts/init.sql` 对比。数据卷的创建时间只能作为排查线索,不能证明表结构是否一致。
|
||
|
||
**方式一:清空重建(推荐,最简单可靠)**
|
||
|
||
```bash
|
||
docker compose down -v && docker compose up -d --build
|
||
```
|
||
|
||
`-v` 会删除 `mysql_data` 和 `uploads_data` 两个卷,**库中数据全部丢失**。执行前务必确认没有需要保留的业务数据,必要时先备份:
|
||
|
||
```bash
|
||
docker compose exec db mysqldump -uroot -pwmms1234 --default-character-set=utf8mb4 wmms > backup.sql
|
||
```
|
||
|
||
**方式二:保留数据并更新结构**
|
||
|
||
需要保留业务数据时,先备份数据库,再根据实际表结构与 `scripts/init.sql` 的差异编写并审核增量 SQL,在备份副本上验证后执行。
|
||
|
||
当前 `scripts/init.sql` 用于空库首次初始化,已包含出入库单号、操作人、备注、分类说明、6 个大类和 28 个子类,以及对应编码规则。库存预警阈值为 0 是有效配置,新库无需清理历史规则。不要将完整初始化脚本直接用于已有业务数据的数据库。
|
||
|
||
## 环境变量
|
||
|
||
| 变量 | 默认值 | 说明 |
|
||
|------|--------|------|
|
||
| DB_DSN | root:wmms1234@tcp(db:3306)/wmms?charset=utf8mb4&parseTime=true | 数据库连接字符串 |
|
||
| GIN_MODE | release | Gin 运行模式 |
|
||
|
||
## 手动构建
|
||
|
||
```bash
|
||
# 构建后端
|
||
docker build -t wmms-backend .
|
||
|
||
# 构建前端
|
||
cd frontend
|
||
docker build -t wmms-frontend .
|
||
|
||
# 启动
|
||
docker-compose up -d
|
||
```
|
||
|
||
## 故障排查
|
||
|
||
### 端口冲突
|
||
|
||
如果 80 或 3306 端口被占用:
|
||
|
||
```bash
|
||
# 查看端口占用
|
||
netstat -ano | findstr ":80"
|
||
netstat -ano | findstr ":3306"
|
||
|
||
# 修改 docker-compose.yml 中的端口映射
|
||
```
|
||
|
||
### 数据库连接失败
|
||
|
||
```bash
|
||
# 检查数据库是否就绪
|
||
docker-compose logs db
|
||
|
||
# 等待数据库启动完成(约10秒)
|
||
```
|
||
|
||
### 接口返回 500:Unknown column 'xxx'
|
||
|
||
**症状**:容器状态全部 healthy,`docker compose logs` 也看不到异常,但某些接口返回 500,例如:
|
||
|
||
```
|
||
Error 1054 (42S22): Unknown column 'description' in 'field list'
|
||
```
|
||
|
||
**原因**:`mysql_data` 卷是旧的,`init.sql` 没有执行,表结构落后于当前代码。详见上文《数据持久化 → ⚠️ 数据卷复用会导致表结构落后于代码》。
|
||
|
||
**确认**:
|
||
|
||
```bash
|
||
docker compose exec db mysql -uroot -pwmms1234 -e "SHOW COLUMNS FROM material_categories;" wmms
|
||
```
|
||
|
||
检查报错涉及的表是否缺少字段,并与当前 `scripts/init.sql` 对比。
|
||
|
||
**解决**:确认数据库和上传文件均无需保留后,可执行 `docker compose down -v && docker compose up -d --build` 重建;需要保留数据时,先备份,再按实际结构差异准备并验证增量 SQL。
|
||
|
||
### 其他排查技巧
|
||
|
||
**哪些表结构会不一致?** 直接在容器里对比:
|
||
|
||
```bash
|
||
# 看当前库到底建了哪些表和列
|
||
docker compose exec db mysql -uroot -pwmms1234 -e "SHOW TABLES;" wmms
|
||
docker compose exec db mysql -uroot -pwmms1234 -e "SHOW COLUMNS FROM inbound_orders;" wmms
|
||
```
|
||
|
||
### 查看容器内部
|
||
|
||
```bash
|
||
# 进入后端容器
|
||
docker exec -it wmms-backend sh
|
||
|
||
# 进入数据库容器
|
||
docker exec -it wmms-db mysql -u root -p
|
||
```
|