# 中州养老部署指南 ## 1. 部署架构 本项目按前后端分离部署: - 前端:`zzyl-ui`,Vue 2 项目,使用 `pnpm` 构建,打包为 Nginx 镜像。 - 后端:`zzyl-admin`,Spring Boot 服务,JDK 11,容器内端口 `9000`。 - 中间件:MySQL 8、Redis 7,镜像使用阿里云镜像源。 - CI:GitHub 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`。 - 阿里云 OSS:Bucket、Endpoint、Region、AccessKeyId、AccessKeySecret。 - 微信小程序:`appId`、`secret`,并把生产域名加入小程序后台白名单。 - 华为云 IoTDA/AMQP:AK、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`。