cicd
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
zpc 2026-03-24 14:37:02 +08:00
parent 97bcb83df3
commit 10d89a85c8

View File

@ -1,6 +1,6 @@
# CI/CD 部署文档
本文档描述学业邑规划项目的 CI/CD 流水线配置,基于 Drone CI + Docker + Harbor 私有镜像仓库。
本文档描述 LiveForum 论坛社区项目的 CI/CD 流水线配置,基于 Drone CI + Docker + Harbor 私有镜像仓库。
## 一、整体架构
@ -10,346 +10,114 @@
| 组件 | 说明 |
|------|------|
| CI 平台 | Drone CI |
| 镜像仓库 | Harbor (`docker.shhmkjgs.cn`) |
| CI 平台 | Drone CI (`192.168.195.25:13080`) |
| 镜像仓库 | Harbor (`192.168.195.25:19900`HTTP |
| 部署方式 | Docker Compose |
| 部署服务器 | `192.168.195.15` |
| 触发条件 | `master` 分支 push 事件 |
## 二、流水线步骤说明
## 二、构建的镜像
当前 `.drone.yml` 定义了 3 个步骤:
| 镜像 | 说明 | Dockerfile | 构建上下文 |
|------|------|-----------|-----------|
| `live-forum/webapi` | 小程序 API.NET 8 | `server/webapi/LiveForum/LiveForum.WebApi/Dockerfile` | `server/webapi/LiveForum` |
| `live-forum/admin-api` | 后台管理 API.NET 8 | `server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Dockerfile` | `server/admin/ZrAdminNetCore` |
| `live-forum/admin-web` | 后台管理前端Vue 3 + Nginx | `server/admin/ZrAdminNetCore/ZR.Vue/Dockerfile` | `server/admin/ZrAdminNetCore/ZR.Vue` |
### 2.1 build-api — 构建小程序 API 镜像
每个镜像打两个标签:`latest` 和 commit SHA 前 8 位(用于回滚)。
- 使用 `plugins/docker` 插件构建并推送镜像
- Dockerfile 路径:`server/MiAssessment/src/MiAssessment.Api/Dockerfile`
- 构建上下文:`server/MiAssessment`
- 镜像地址:`docker.shhmkjgs.cn/mi-assessment/api`
- 标签:`latest` + commit SHA 前 8 位
## 三、流水线步骤
### 2.2 build-admin — 构建后台管理系统镜像
`.drone.yml` 定义了 4 个步骤:
- Dockerfile 路径:`server/MiAssessment/src/MiAssessment.Admin/Dockerfile`
- 构建上下文:`server/MiAssessment`
- 镜像地址:`docker.shhmkjgs.cn/mi-assessment/admin`
- 标签策略同上
1. `build-webapi` — 构建小程序 API 镜像
2. `build-admin-api` — 构建后台管理 API 镜像
3. `build-admin-web` — 构建后台管理前端镜像
4. `deploy` — SSH 部署(等待前三步完成)
> `build-api``build-admin` 默认并行执行。
> 三个构建步骤默认并行执行deploy 步骤通过 `depends_on` 等待全部完成后执行。
### 2.3 deploy — SSH 部署
## 四、基础镜像(内网 Harbor
- 等待两个构建步骤完成后执行(`depends_on`
- SSH 连接到目标服务器 `192.168.195.15`
- 执行 `docker compose pull` 拉取最新镜像
- 执行 `docker compose up -d` 重启服务
所有 Dockerfile 的基础镜像已切换到内网 Harbor避免依赖外网
## 三、前置条件
| 基础镜像 | 内网地址 | 用途 |
|---------|---------|------|
| `dotnet/aspnet:8.0` | `192.168.195.25:19900/library/dotnet/aspnet:8.0` | .NET 运行时 |
| `dotnet/sdk:8.0` | `192.168.195.25:19900/library/dotnet/sdk:8.0` | .NET 构建 |
| `node:18-alpine` | `192.168.195.25:19900/library/node:18-alpine` | Vue 前端构建 |
| `nginx:alpine` | `192.168.195.25:19900/library/nginx:alpine` | 前端运行 |
### 3.1 Drone CI 配置
如需更新基础镜像在能访问外网的机器上拉取、tag、push
1. 在 Drone 管理界面激活本仓库
2. 确保仓库根目录存在 `.drone.yml` 文件
3. 配置以下 Secrets在 Drone 仓库设置 → Secrets 中添加):
```bash
docker pull mcr.microsoft.com/dotnet/aspnet:8.0
docker tag mcr.microsoft.com/dotnet/aspnet:8.0 192.168.195.25:19900/library/dotnet/aspnet:8.0
docker push 192.168.195.25:19900/library/dotnet/aspnet:8.0
```
| Secret 名称 | 说明 | 示例 |
|-------------|------|------|
| `harbor_username` | Harbor 仓库用户名 | `admin` |
| `harbor_password` | Harbor 仓库密码 | `****` |
| `ssh_username` | 部署服务器 SSH 用户名 | `root` |
| `ssh_password` | 部署服务器 SSH 密码 | `****` |
## 五、前置条件
### 3.2 Harbor 镜像仓库
### 5.1 Drone CI Secrets
1. 在 Harbor 中创建项目 `mi-assessment`
2. 确保推送账号有该项目的写权限
3. 当前使用 HTTP`insecure: true`),生产环境建议配置 HTTPS
在 Drone 仓库设置 → Secrets 中配置:
### 3.3 部署服务器
| Secret 名称 | 说明 |
|-------------|------|
| `harbor_username` | Harbor 仓库用户名 |
| `harbor_password` | Harbor 仓库密码 |
| `ssh_username` | 部署服务器 SSH 用户名 |
| `ssh_password` | 部署服务器 SSH 密码 |
服务器上需要准备:
### 5.2 Harbor 镜像仓库
1. 在 Harbor 中创建项目 `live-forum``library`
2. `library` 为公开项目存放基础镜像pull 不需要登录)
3. `live-forum` 存放业务镜像,推送需要认证
4. 当前使用 HTTP`insecure: true`
### 5.3 部署服务器192.168.195.15
1. 安装 Docker 和 Docker Compose
2. 创建部署目录和 compose 文件:
2. 配置 Docker 信任 HarborHTTP
```bash
mkdir -p /disk/docker-compose/mi-assessment
```
3. 编写 `docker-compose.yml`(参考模板):
```yaml
version: "3.8"
services:
api:
image: docker.shhmkjgs.cn/mi-assessment/api:latest
container_name: mi-assessment-api
ports:
- "5238:5238"
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ConnectionStrings__DefaultConnection=Server=sqlserver;Database=MiAssessment_Business;User Id=sa;Password=****;TrustServerCertificate=true
- ConnectionStrings__AdminConnection=Server=sqlserver;Database=MiAssessment_Admin;User Id=sa;Password=****;TrustServerCertificate=true
- Redis__ConnectionString=redis:6379
depends_on:
- sqlserver
- redis
restart: always
admin:
image: docker.shhmkjgs.cn/mi-assessment/admin:latest
container_name: mi-assessment-admin
ports:
- "8080:8080"
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ConnectionStrings__DefaultConnection=Server=sqlserver;Database=MiAssessment_Business;User Id=sa;Password=****;TrustServerCertificate=true
- ConnectionStrings__AdminConnection=Server=sqlserver;Database=MiAssessment_Admin;User Id=sa;Password=****;TrustServerCertificate=true
- Redis__ConnectionString=redis:6379
depends_on:
- sqlserver
- redis
restart: always
sqlserver:
image: mcr.microsoft.com/mssql/server:2022-latest
container_name: mi-assessment-db
ports:
- "1433:1433"
environment:
- ACCEPT_EULA=Y
- MSSQL_SA_PASSWORD=YourStrong!Passw0rd
volumes:
- sqlserver-data:/var/opt/mssql
restart: always
redis:
image: redis:7-alpine
container_name: mi-assessment-redis
ports:
- "6379:6379"
volumes:
- redis-data:/data
restart: always
volumes:
sqlserver-data:
redis-data:
```
4. 配置 Docker 信任 Harbor 仓库HTTP 方式):
```bash
# 编辑 /etc/docker/daemon.json
# /etc/docker/daemon.json
{
"insecure-registries": ["docker.shhmkjgs.cn"]
"insecure-registries": ["192.168.195.25:19900"]
}
# 重启 Docker
systemctl restart docker
```
5. 登录 Harbor
3. 登录 Harbor
```bash
docker login docker.shhmkjgs.cn
docker login 192.168.195.25:19900
```
## 四、.drone.yml 配置详解
```yaml
---
kind: pipeline
type: docker
name: mi-assessment
# 触发条件master 分支的 push 事件
trigger:
branch:
- master
event:
- push
steps:
# 步骤1构建 API 镜像
- name: build-api
image: plugins/docker # Drone 官方 Docker 构建插件
settings:
registry: docker.shhmkjgs.cn # Harbor 地址
repo: docker.shhmkjgs.cn/mi-assessment/api # 镜像全名
dockerfile: server/MiAssessment/src/MiAssessment.Api/Dockerfile
context: server/MiAssessment # Docker 构建上下文
tags:
- latest
- ${DRONE_COMMIT_SHA:0:8} # commit 短哈希作为版本标签
username:
from_secret: harbor_username
password:
from_secret: harbor_password
insecure: true # 允许 HTTP 推送
# 步骤2构建 Admin 镜像
- name: build-admin
image: plugins/docker
settings:
registry: docker.shhmkjgs.cn
repo: docker.shhmkjgs.cn/mi-assessment/admin
dockerfile: server/MiAssessment/src/MiAssessment.Admin/Dockerfile
context: server/MiAssessment
tags:
- latest
- ${DRONE_COMMIT_SHA:0:8}
username:
from_secret: harbor_username
password:
from_secret: harbor_password
insecure: true
# 步骤3SSH 部署(等待构建完成)
- name: deploy
image: appleboy/drone-ssh # SSH 远程执行插件
settings:
host: 192.168.195.15
username:
from_secret: ssh_username
password:
from_secret: ssh_password
port: 22
script:
- cd /disk/docker-compose/mi-assessment
- docker compose pull # 拉取最新镜像
- docker compose up -d # 重启容器
depends_on:
- build-api
- build-admin
```
## 五、如何修改和扩展
### 5.1 添加多环境支持
如果需要区分 dev / staging / production可以用分支触发不同流水线
```yaml
---
kind: pipeline
type: docker
name: deploy-dev
trigger:
branch:
- develop
event:
- push
steps:
- name: build-api
image: plugins/docker
settings:
repo: docker.shhmkjgs.cn/mi-assessment/api
tags:
- dev-latest
- dev-${DRONE_COMMIT_SHA:0:8}
# ... 其他配置同上
- name: deploy-dev
image: appleboy/drone-ssh
settings:
host: 192.168.195.20 # 开发环境服务器
script:
- cd /disk/docker-compose/mi-assessment-dev
- docker compose pull
- docker compose up -d
depends_on:
- build-api
```
### 5.2 添加单元测试步骤
在构建之前加入测试:
```yaml
steps:
- name: test
image: mcr.microsoft.com/dotnet/sdk:10.0-preview
commands:
- cd server/MiAssessment
- dotnet restore
- dotnet test --no-restore --verbosity normal
- name: build-api
# ...
depends_on:
- test
```
### 5.3 添加构建通知
使用钉钉或企业微信通知构建结果:
```yaml
- name: notify
image: plugins/webhook
settings:
urls: https://oapi.dingtalk.com/robot/send?access_token=xxxx
content_type: application/json
template: |
{
"msgtype": "text",
"text": {
"content": "MiAssessment 部署完成\n分支: {{build.branch}}\n提交: {{build.commit}}\n状态: {{build.status}}"
}
}
depends_on:
- deploy
when:
status:
- success
- failure
```
### 5.4 添加 admin-web 前端构建
如果后台前端需要独立构建和部署:
```yaml
- name: build-admin-web
image: plugins/docker
settings:
registry: docker.shhmkjgs.cn
repo: docker.shhmkjgs.cn/mi-assessment/admin-web
dockerfile: server/MiAssessment/src/MiAssessment.Admin/admin-web/Dockerfile
context: server/MiAssessment/src/MiAssessment.Admin/admin-web
tags:
- latest
- ${DRONE_COMMIT_SHA:0:8}
username:
from_secret: harbor_username
password:
from_secret: harbor_password
insecure: true
```
4. 部署目录:`/disk/docker-compose/live-forum-new`
## 六、常见问题
### Q: 构建失败怎么排查
### Q: 构建时拉取基础镜像失败?
1. 在 Drone 界面查看失败步骤的日志
2. 常见原因:
- Secrets 未配置或配置错误
- Dockerfile 路径不对
- Harbor 仓库项目不存在
- 网络不通CI Runner 无法访问 Harbor
基础镜像需要提前推送到内网 Harbor。Drone CI 的 Docker daemon 也需要配置 `insecure-registries`(在 `.drone.yml` 中通过 `insecure: true` 处理推送,但 Dockerfile 中的 FROM 拉取需要 runner 层面配置)。
### Q: Harbor 认证失败unauthorized
检查 Drone Secrets 中的 `harbor_username` / `harbor_password` 是否正确且未过期。
### Q: 部署后服务没更新?
1. 检查 `docker compose pull` 是否拉到了新镜像
2. 确认服务器 Docker 已配置 `insecure-registries`
3. 检查容器是否正常启动`docker compose ps` / `docker compose logs`
3. 检查容器状态:`docker compose ps` / `docker compose logs`
### Q: 如何回滚?
使用 commit SHA 标签回滚
使用 commit SHA 标签:
```bash
# 在服务器上修改 docker-compose.yml 中的镜像标签
@ -357,6 +125,10 @@ steps:
docker compose up -d
```
### Q: admin-web 构建报 COPY failed: stat app/dist
`vite.config.js``outDir` 配置了服务器绝对路径Dockerfile 中已通过 `npx vite build --mode production --outDir dist` 覆盖输出到 `dist` 目录。
### Q: 如何手动触发构建?
在 Drone 界面找到对应仓库,点击 "New Build" 按钮,选择分支即可。
在 Drone 界面找到对应仓库,点击 "New Build",选择分支即可。