Files
zhongzhou-elderly-care/doc/部署指南.md

271 lines
11 KiB
Markdown
Raw Permalink 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.
# 中州养老部署指南
## 1. 部署架构
本项目按前后端分离部署:
- 前端:`zzyl-ui`Vue 2 项目,使用 `pnpm` 构建,打包为 Nginx 镜像。
- 后端:`zzyl-admin`Spring Boot 服务JDK 11容器内端口 `9000`
- 中间件MySQL 8、Redis 7镜像使用阿里云镜像源。
- CIGitHub Actions 构建并推送 `zzyl-admin``zzyl-ui` 两个镜像。
- CD服务器上手动执行 Docker Compose所有运行时变量统一写在 `deploy/compose/.env`
生产入口为前端服务:`http://服务器IP或域名:${UI_PORT}/`。前端 `/prod-api/` 会由 Nginx 转发到后端 `zzyl-admin:9000`
部署使用的基础中间件镜像:
- MySQL`registry.cn-hangzhou.aliyuncs.com/pull-image/mysql:8.0`
- Redis`registry.cn-hangzhou.aliyuncs.com/pull-image/redis:7-alpine`
- Nginx`registry.cn-hangzhou.aliyuncs.com/pull-image/nginx:mainline-alpine`
## 2. 需要准备的材料
- Linux 服务器,建议 2 核 4G 以上,已安装 Docker Engine、Docker Compose Plugin、Git、curl。
- 阿里云 ACR 或其他 Docker Registry用于保存后端和前端镜像。
- GitHub Secrets`ACR_REGISTRY``ACR_USERNAME``ACR_PASSWORD``IMAGE_NAMESPACE`
- 域名和 DNS 解析;如对外提供 HTTPS还需要证书或上层反向代理网关。
- 数据库初始化脚本:`sql/dev0302.sql``sql/quartz.sql`
- 阿里云 OSSBucket、Endpoint、Region、AccessKeyId、AccessKeySecret。
- 微信小程序:`appId``secret`,并把生产域名加入小程序后台白名单。
- 华为云 IoTDA/AMQPAK、SK、ProjectId、Endpoint、RegionId、AMQP Host、AccessKey、AccessCode、QueueName。
- 百度千帆AccessKey、SecretKey、模型名。
## 3. CI 构建流程
工作流文件:`.github/workflows/build-and-push.yml`
触发方式:
- 推送到 `main``master`
- 推送 `v*` Tag。
- 在 GitHub Actions 手动执行 `workflow_dispatch`
CI 会执行:
1. 使用 JDK 11 执行 `mvn -B clean package -DskipTests`
2. 基于 `zzyl-admin/Dockerfile` 构建并推送 `zzyl-admin:${tag}`
3. 基于 `zzyl-ui/Dockerfile` 使用 `pnpm install --frozen-lockfile && pnpm build:prod` 构建并推送 `zzyl-ui:${tag}`
4. 分支构建会额外推送 `latest` 标签。
镜像地址示例:
```text
registry.cn-hangzhou.aliyuncs.com/your-namespace/zzyl-admin:latest
registry.cn-hangzhou.aliyuncs.com/your-namespace/zzyl-ui:latest
```
## 4. 拉取项目与环境变量
推荐目录:
```bash
mkdir -p /site
mkdir -p /data/zzyl/{logs,uploadPath}
```
如果当前用户没有权限创建 `/site`,请使用 `sudo mkdir -p /site`,并把目录授权给部署用户。
在服务器直接拉取本项目:
```bash
cd /site
git clone https://github.com/shenjianZ/zhongzhou-elderly-care.git
cd zhongzhou-elderly-care
cp deploy/compose/.env.example deploy/compose/.env
```
后续部署都在项目目录 `/site/zhongzhou-elderly-care` 内操作,不需要把 Compose 或 SQL 文件复制到其他目录。
编辑 `deploy/compose/.env`,至少修改:
- `ZZYL_ADMIN_IMAGE``ZZYL_UI_IMAGE`
- `UI_PORT`,如果宿主机 Nginx 也监听 80建议改为 `8080`
- `MYSQL_ROOT_PASSWORD``MYSQL_APP_PASSWORD``MYSQL_PASSWORD`
- `REDIS_PASSWORD`
- `TOKEN_SECRET``DRUID_LOGIN_PASSWORD`
- OSS、微信、华为云、百度千帆相关变量
注意:`MYSQL_APP_USER/MYSQL_APP_PASSWORD` 必须与 `MYSQL_USERNAME/MYSQL_PASSWORD` 保持一致。
### 4.1 环境变量填写要求
基础与镜像变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `TZ` | 容器时区 | 否 | 默认 `Asia/Shanghai` |
| `UI_PORT` | 前端对外端口 | 否 | 默认 `80`;宿主机已有 Nginx 时建议改为 `8080` |
| `APP_PORT` | 后端对外端口 | 否 | 默认 `9000`;主要用于排查,前端通过容器网络访问后端 |
| `ZZYL_ADMIN_IMAGE` | 后端镜像地址 | 是 | GitHub Actions 推送的 `zzyl-admin` 镜像 |
| `ZZYL_UI_IMAGE` | 前端镜像地址 | 是 | GitHub Actions 推送的 `zzyl-ui` 镜像 |
MySQL 变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `MYSQL_PORT` | MySQL 对外端口 | 否 | 默认 `3306`;端口冲突时修改 |
| `MYSQL_DATABASE` | 业务库名 | 否 | 默认 `zzyl` |
| `MYSQL_ROOT_PASSWORD` | MySQL root 密码 | 是 | 首次初始化数据库时使用 |
| `MYSQL_APP_USER` | 应用数据库账号 | 否 | 默认 `zzyl` |
| `MYSQL_APP_PASSWORD` | 应用数据库账号密码 | 是 | MySQL 容器创建应用账号时使用 |
| `MYSQL_URL` | 后端 JDBC 地址 | 否 | 使用 Compose 内置 MySQL 时保留默认即可 |
| `MYSQL_USERNAME` | 后端连接 MySQL 用户名 | 否 | 默认应与 `MYSQL_APP_USER` 一致 |
| `MYSQL_PASSWORD` | 后端连接 MySQL 密码 | 是 | 必须与 `MYSQL_APP_PASSWORD` 一致 |
Redis 与后端运行变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `REDIS_PORT` | Redis 对外端口 | 否 | 默认 `6379`;端口冲突时修改 |
| `REDIS_HOST` | 后端连接 Redis 主机 | 否 | 使用 Compose 内置 Redis 时保留 `zzyl-redis` |
| `REDIS_PASSWORD` | Redis 密码 | 是 | Redis 容器启动和后端连接都会使用 |
| `REDIS_DATABASE` | Redis 数据库索引 | 否 | 默认 `2` |
| `APP_LOG_DIR` | 后端日志挂载目录 | 否 | 默认 `/data/zzyl/logs` |
| `APP_PROFILE_DIR` | 文件上传挂载目录 | 否 | 默认 `/data/zzyl/uploadPath` |
| `RUOYI_PROFILE` | 后端文件存储路径 | 否 | 应与 `APP_PROFILE_DIR` 保持一致 |
| `TOKEN_SECRET` | 登录令牌签名密钥 | 是 | 生产环境必须改成足够长的随机字符串 |
| `TOKEN_EXPIRE_TIME` | 登录令牌有效期 | 否 | 默认 `3600` 秒 |
| `DRUID_LOGIN_USERNAME` | Druid 监控页用户名 | 否 | 默认 `ruoyi` |
| `DRUID_LOGIN_PASSWORD` | Druid 监控页密码 | 是 | 生产环境必须修改 |
| `DEPT_NURSING_ID` | 护理部门 ID | 否 | 默认 `201`,需与初始化数据中的部门一致 |
阿里云 OSS 变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `ALIYUN_OSS_DOMAIN` | OSS 访问域名 | 按功能 | 文件访问 URL 拼接使用 |
| `ALIYUN_OSS_ENDPOINT` | OSS API Endpoint | 按功能 | 上传文件时使用 |
| `ALIYUN_OSS_BUCKET` | OSS Bucket 名称 | 按功能 | 上传目标 Bucket |
| `ALIYUN_OSS_REGION` | OSS Region | 按功能 | 例如 `cn-hangzhou` |
| `ALIYUN_OSS_ACCESS_KEY_ID` | OSS AccessKey ID | 按功能 | 上传文件时使用 |
| `ALIYUN_OSS_SECRET_ACCESS_KEY` | OSS AccessKey Secret | 按功能 | 上传文件时使用 |
说明OSS 不影响系统启动,但上传文件、图片、健康评估报告等功能需要填写。
百度千帆与微信变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `BAIDU_ACCESS_KEY` | 百度千帆 AccessKey | 按功能 | 健康评估 AI 生成时使用 |
| `BAIDU_SECRET_KEY` | 百度千帆 SecretKey | 按功能 | 健康评估 AI 生成时使用 |
| `BAIDU_QIANFAN_MODEL` | 百度千帆模型名 | 按功能 | 默认 `ERNIE-4.0-8K` |
| `WECHAT_MINI_PROGRAM_APP_ID` | 微信小程序 AppID | 按功能 | 小程序登录和获取手机号使用 |
| `WECHAT_MINI_PROGRAM_SECRET` | 微信小程序 Secret | 按功能 | 小程序登录和获取手机号使用 |
说明:百度千帆和微信不影响后台管理系统启动;未填写时,对应业务功能会失败。
华为云 IoTDA/AMQP 变量:
| 变量 | 作用 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| `HUAWEI_CLOUD_AK` | 华为云 AK | 是 | IoTDA SDK 客户端启动使用 |
| `HUAWEI_CLOUD_SK` | 华为云 SK | 是 | IoTDA SDK 客户端启动使用 |
| `HUAWEI_CLOUD_REGION_ID` | 华为云区域 ID | 是 | 例如 `cn-east-3` |
| `HUAWEI_CLOUD_ENDPOINT` | IoTDA HTTPS 接入地址 | 是 | 设备管理接口使用 |
| `HUAWEI_CLOUD_PROJECT_ID` | 华为云 ProjectId | 是 | IoTDA SDK 鉴权使用 |
| `HUAWEI_CLOUD_AMQP_HOST` | AMQP 接入地址 | 是 | 设备消息消费客户端启动使用 |
| `HUAWEI_CLOUD_AMQP_ACCESS_KEY` | AMQP AccessKey | 是 | AMQP 连接用户名组成部分 |
| `HUAWEI_CLOUD_AMQP_ACCESS_CODE` | AMQP AccessCode | 是 | AMQP 连接密码 |
| `HUAWEI_CLOUD_AMQP_QUEUE_NAME` | AMQP 队列名称 | 是 | 默认通常为 `DefaultQueue` |
说明:当前后端启动时会自动启动华为云 AMQP 消费客户端,所以 `HUAWEI_CLOUD_*` 不能保留 `change_me` 占位值。
### 4.2 中间件清单
| 中间件 | 用途 | 是否必须 |
| --- | --- | --- |
| MySQL 8 | 存储业务数据、系统用户、菜单、养老业务数据、Quartz 任务表 | 必须 |
| Redis 7 | 缓存、验证码、登录 Token、系统临时数据 | 必须 |
| Nginx | 部署前端 `zzyl-ui` 静态资源,并反向代理 `/prod-api/` 到后端 | 必须,已内置在前端镜像中 |
| Docker / Docker Compose | 容器化部署 MySQL、Redis、后端、前端 | 必须 |
| Quartz | 后端定时任务调度,表结构来自 `sql/quartz.sql` | 必须,随后端运行 |
| Druid | 后端数据库连接池和监控页面 | 必须,随 Java 应用运行 |
第三方云服务不算传统中间件,但部署时也会用到:
| 服务 | 用途 | 是否必须 |
| --- | --- | --- |
| 阿里云 OSS | 文件、图片、报告上传存储 | 按功能需要 |
| 华为云 IoTDA / AMQP | 设备管理、设备消息消费 | 当前启动时必须配置 |
| 百度千帆 | 健康评估 AI 生成 | 按功能需要 |
| 微信小程序接口 | 小程序登录、获取手机号 | 按功能需要 |
| 阿里云 ACR 或其他镜像仓库 | 保存 CI 构建出的前后端镜像 | 部署镜像时必须 |
## 5. 首次部署
进入部署目录:
```bash
cd /site/zhongzhou-elderly-care/deploy/compose
docker compose --env-file .env up -d mysql redis
```
初始化数据库:
```bash
set -a
. ./.env
set +a
docker exec -i zzyl-mysql mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" < ../../sql/dev0302.sql
docker exec -i zzyl-mysql mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" zzyl < ../../sql/quartz.sql
```
启动完整系统:
```bash
docker compose --env-file .env pull
docker compose --env-file .env up -d
docker compose --env-file .env ps
```
## 6. 进入系统
浏览器访问:
```text
http://服务器IP或域名/
```
如果 `UI_PORT` 不是 `80`,访问:
```text
http://服务器IP或域名:${UI_PORT}/
```
默认后台账号:
- 用户名:`admin`
- 密码:`admin123`
首次登录后请立即修改管理员密码,并检查系统管理、养老业务菜单是否正常显示。
## 7. 升级与验证
升级:
```bash
cd /site/zhongzhou-elderly-care
git pull
cd deploy/compose
docker compose --env-file .env pull
docker compose --env-file .env up -d
docker image prune -f
```
验证:
```bash
docker compose --env-file .env ps
docker logs zzyl-admin --tail 200
docker logs zzyl-ui --tail 100
curl -I http://127.0.0.1:${UI_PORT}/
```
常见问题:
- 前端打不开:检查 `zzyl-ui` 容器、`UI_PORT`、安全组和防火墙。
- 登录验证码失败:检查 `/prod-api/captchaImage` 是否被 Nginx 转发到后端。
- 后端启动失败:优先查看 MySQL、Redis、华为云 IoTDA/AMQP、OSS、百度千帆变量。
- 上传失败:检查 OSS 配置和 `RUOYI_PROFILE=/data/zzyl/uploadPath`