JewelryMall/CI-CD部署文档.md
zpc dd95b4ee6f
Some checks failed
continuous-integration/drone/push Build is failing
cicd
2026-04-09 11:56:24 +08:00

16 KiB
Raw Blame History

CI/CD 部署文档

本文档描述基于 Drone CI + Docker + Harbor 私有镜像仓库(内网)的 CI/CD 流水线配置。其他项目可参考本文档搭建自己的 CI/CD 流程。

一、整体架构

代码推送 (master) → Drone CI 触发 → 构建 Docker 镜像 → 推送内网 Harbor → SSH 部署到服务器
组件 地址/说明
CI 平台 Drone CI (192.168.195.25:13080)
镜像仓库 Harbor (192.168.195.25:19900HTTP
部署方式 Docker Compose
部署服务器 192.168.195.15(可按项目分配不同服务器)
触发条件 main 分支 push 事件

二、快速开始(新项目接入指南)

2.1 在 Harbor 创建项目

  1. 访问 Harbor 管理界面:http://192.168.195.25:19900
  2. 创建一个新项目,名称使用项目标识(如 my-project
  3. 设置为私有项目(推送需要认证)

2.2 在 Drone CI 激活仓库

  1. 访问 Drone CIhttp://192.168.195.25:13080
  2. 使用 Gitea/Gogs 账号登录Drone 与代码仓库联动)
  3. 在仓库列表中找到你的项目,点击 Activate
  4. 进入仓库设置 → Secrets,添加以下密钥:
Secret 名称 说明 示例值
harbor_username Harbor 仓库用户名 admin
harbor_password Harbor 仓库密码 Harbor12345
ssh_username 部署服务器 SSH 用户名 root
ssh_password 部署服务器 SSH 密码 your-password

2.3 编写 .drone.yml

在项目根目录创建 .drone.yml,参考下方模板。

2.4 编写 Dockerfile

为每个需要构建的服务编写 Dockerfile。

2.5 编写 docker-compose.yml

在部署服务器上创建 docker-compose 配置。

2.6 推送代码触发流水线

推送代码到 master 分支Drone 会自动触发构建和部署。

三、.drone.yml 配置模板

3.1 单服务项目模板

适用于只有一个服务需要构建和部署的项目:

---
kind: pipeline
type: docker
name: my-project                          # ← 改为你的项目名

trigger:
  branch:
    - master                              # ← 触发分支,可改为 main
  event:
    - push

steps:
  # ==================== 构建并推送镜像 ====================
  - name: build
    image: plugins/docker
    settings:
      registry: 192.168.195.25:19900
      repo: 192.168.195.25:19900/my-project/app    # ← 改为 Harbor项目名/镜像名
      dockerfile: Dockerfile                         # ← Dockerfile 路径
      context: .                                     # ← 构建上下文目录
      tags:
        - latest
        - ${DRONE_COMMIT_SHA:0:8}                    # commit SHA 前8位用于回滚
      username:
        from_secret: harbor_username
      password:
        from_secret: harbor_password
      insecure: true                                 # Harbor 使用 HTTP 时必须

  # ==================== 部署到服务器 ====================
  - name: deploy
    image: appleboy/drone-ssh
    settings:
      host: 192.168.195.15                           # ← 改为你的部署服务器 IP
      username:
        from_secret: ssh_username
      password:
        from_secret: ssh_password
      port: 22
      script:
        - cd /disk/docker-compose/my-project         # ← 改为服务器上的部署目录
        - docker compose pull
        - docker compose up -d
    depends_on:
      - build

3.2 多服务项目模板

适用于有多个服务(如 API + Admin需要分别构建的项目

---
kind: pipeline
type: docker
name: my-project

trigger:
  branch:
    - master
  event:
    - push

steps:
  # ==================== 构建服务 A ====================
  - name: build-service-a
    image: plugins/docker
    settings:
      registry: 192.168.195.25:19900
      repo: 192.168.195.25:19900/my-project/service-a
      dockerfile: src/ServiceA/Dockerfile
      context: src
      tags:
        - latest
        - ${DRONE_COMMIT_SHA:0:8}
      username:
        from_secret: harbor_username
      password:
        from_secret: harbor_password
      insecure: true

  # ==================== 构建服务 B ====================
  - name: build-service-b
    image: plugins/docker
    settings:
      registry: 192.168.195.25:19900
      repo: 192.168.195.25:19900/my-project/service-b
      dockerfile: src/ServiceB/Dockerfile
      context: src
      tags:
        - latest
        - ${DRONE_COMMIT_SHA:0:8}
      username:
        from_secret: harbor_username
      password:
        from_secret: harbor_password
      insecure: true

  # ==================== 部署到服务器 ====================
  - name: deploy
    image: appleboy/drone-ssh
    settings:
      host: 192.168.195.15
      username:
        from_secret: ssh_username
      password:
        from_secret: ssh_password
      port: 22
      script:
        - cd /disk/docker-compose/my-project
        - docker compose pull
        - docker compose up -d
    depends_on:
      - build-service-a                              # 等待所有构建完成
      - build-service-b

多个 build 步骤默认并行执行deploy 通过 depends_on 等待全部完成后执行。

四、MiAssessment 项目实际配置

本项目(学业邑规划)的实际配置如下,供参考:

4.1 构建的镜像

镜像 说明 Dockerfile 构建上下文
mi-assessment/api 小程序 API.NET 10 server/MiAssessment/src/MiAssessment.Api/Dockerfile server/MiAssessment
mi-assessment/admin 后台管理 API + 前端(.NET 10内含 admin-web 构建产物) server/MiAssessment/src/MiAssessment.Admin/Dockerfile server/MiAssessment

每个镜像打两个标签:latest 和 commit SHA 前 8 位(用于回滚)。

4.2 流水线步骤

.drone.yml 定义了 3 个步骤:

  1. build-api — 构建小程序 API 镜像
  2. build-admin — 构建后台管理 API 镜像(并行)
  3. deploy — SSH 部署(等待前两步完成)

4.3 完整 .drone.yml

---
kind: pipeline
type: docker
name: mi-assessment

trigger:
  branch:
    - master
  event:
    - push

steps:
  - name: build-api
    image: plugins/docker
    settings:
      registry: 192.168.195.25:19900
      repo: 192.168.195.25:19900/mi-assessment/api
      dockerfile: server/MiAssessment/src/MiAssessment.Api/Dockerfile
      context: server/MiAssessment
      tags:
        - latest
        - ${DRONE_COMMIT_SHA:0:8}
      username:
        from_secret: harbor_username
      password:
        from_secret: harbor_password
      insecure: true

  - name: build-admin
    image: plugins/docker
    settings:
      registry: 192.168.195.25:19900
      repo: 192.168.195.25:19900/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

  - name: deploy
    image: appleboy/drone-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 为什么需要内网基础镜像

内网环境无法直接拉取 Docker Hub / MCR 的镜像,需要提前将基础镜像推送到内网 Harbor 的 library 项目中。

5.2 推送基础镜像

在能访问外网的机器上执行:

# 一键推送(如果项目提供了脚本)
bash scripts/push-base-images.sh

# 手动推送单个镜像
docker pull mcr.microsoft.com/dotnet/aspnet:10.0-preview
docker tag mcr.microsoft.com/dotnet/aspnet:10.0-preview 192.168.195.25:19900/library/dotnet/aspnet:10.0-preview
docker push 192.168.195.25:19900/library/dotnet/aspnet:10.0-preview

5.3 常用基础镜像

基础镜像 内网地址 用途
dotnet/aspnet:10.0-preview 192.168.195.25:19900/library/dotnet/aspnet:10.0-preview .NET 运行时
dotnet/sdk:10.0-preview 192.168.195.25:19900/library/dotnet/sdk:10.0-preview .NET 构建
node:20-alpine 192.168.195.25:19900/library/node:20-alpine Node.js 前端构建
python:3.12-slim 192.168.195.25:19900/library/python:3.12-slim Python 项目
golang:1.22-alpine 192.168.195.25:19900/library/golang:1.22-alpine Go 项目
nginx:alpine 192.168.195.25:19900/library/nginx:alpine 静态文件服务

5.4 Dockerfile 中使用内网镜像

# 使用内网 Harbor 的基础镜像
FROM 192.168.195.25:19900/library/node:20-alpine AS build
WORKDIR /app
COPY . .
RUN npm install && npm run build

FROM 192.168.195.25:19900/library/nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html

六、部署服务器配置

6.1 安装 Docker 和 Docker Compose

# CentOS / RHEL
yum install -y docker-ce docker-compose-plugin

# Ubuntu / Debian
apt-get install -y docker-ce docker-compose-plugin

# 启动 Docker
systemctl enable docker
systemctl start docker

6.2 配置信任内网 HarborHTTP

由于 Harbor 使用 HTTP 而非 HTTPS需要配置 Docker 信任该仓库:

# 编辑 /etc/docker/daemon.json
{
  "insecure-registries": ["192.168.195.25:19900"]
}

# 重启 Docker
systemctl restart docker

6.3 登录 Harbor

docker login 192.168.195.25:19900
# 输入用户名和密码

6.4 创建部署目录

mkdir -p /disk/docker-compose/my-project
cd /disk/docker-compose/my-project

6.5 编写 docker-compose.yml

示例(单服务):

version: "3.8"

services:
  app:
    image: 192.168.195.25:19900/my-project/app:latest
    container_name: my-project-app
    ports:
      - "8080:8080"
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
    restart: unless-stopped

示例(多服务,参考 MiAssessment

version: "3.8"

services:
  api:
    image: 192.168.195.25:19900/mi-assessment/api:latest
    container_name: mi-assessment-api
    ports:
      - "5000:8080"
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
    volumes:
      - ./appsettings.api.json:/app/appsettings.Production.json
    restart: unless-stopped

  admin:
    image: 192.168.195.25:19900/mi-assessment/admin:latest
    container_name: mi-assessment-admin
    ports:
      - "5001:8080"
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
    volumes:
      - ./appsettings.admin.json:/app/appsettings.Production.json
    restart: unless-stopped

七、Drone CI 配置详解

7.1 关键字段说明

字段 说明
kind: pipeline 流水线类型
type: docker 使用 Docker 执行器
trigger.branch 触发分支
trigger.event 触发事件push / pull_request / tag
settings.registry Harbor 仓库地址
settings.repo 镜像完整路径(含 registry
settings.dockerfile Dockerfile 相对路径
settings.context Docker 构建上下文目录
settings.tags 镜像标签列表
settings.insecure 允许 HTTP 推送Harbor 非 HTTPS 时必须)
from_secret 引用 Drone Secrets 中的密钥
depends_on 步骤依赖,等待指定步骤完成后执行

7.2 常用 Drone 变量

变量 说明 示例值
${DRONE_COMMIT_SHA} 完整 commit SHA a1b2c3d4e5f6...
${DRONE_COMMIT_SHA:0:8} commit SHA 前 8 位 a1b2c3d4
${DRONE_BRANCH} 当前分支名 master
${DRONE_TAG} Git 标签tag 事件时) v1.0.0
${DRONE_BUILD_NUMBER} 构建编号 42
${DRONE_REPO_NAME} 仓库名 mi-assessment

7.3 高级配置示例

按分支部署到不同环境

---
kind: pipeline
type: docker
name: deploy-staging

trigger:
  branch:
    - develop
  event:
    - push

steps:
  - name: build
    image: plugins/docker
    settings:
      registry: 192.168.195.25:19900
      repo: 192.168.195.25:19900/my-project/app
      tags:
        - staging
        - ${DRONE_COMMIT_SHA:0:8}
      # ... 其他配置同上

  - name: deploy-staging
    image: appleboy/drone-ssh
    settings:
      host: 192.168.195.20                           # 测试服务器
      username:
        from_secret: ssh_username
      password:
        from_secret: ssh_password
      port: 22
      script:
        - cd /disk/docker-compose/my-project-staging
        - docker compose pull
        - docker compose up -d
    depends_on:
      - build

---
kind: pipeline
type: docker
name: deploy-production

trigger:
  branch:
    - master
  event:
    - push

steps:
  - name: build
    image: plugins/docker
    settings:
      registry: 192.168.195.25:19900
      repo: 192.168.195.25:19900/my-project/app
      tags:
        - latest
        - ${DRONE_COMMIT_SHA:0:8}
      # ... 其他配置同上

  - name: deploy-production
    image: appleboy/drone-ssh
    settings:
      host: 192.168.195.15                           # 生产服务器
      # ... 其他配置同上

添加构建通知(钉钉/企业微信)

  - name: notify
    image: plugins/webhook
    settings:
      urls: https://oapi.dingtalk.com/robot/send?access_token=xxx
      content_type: application/json
      template: |
        {
          "msgtype": "text",
          "text": {
            "content": "✅ {{repo.name}} 部署成功\n分支: {{build.branch}}\n提交: {{build.commit}}"
          }
        }        
    depends_on:
      - deploy
    when:
      status:
        - success

八、新项目接入清单

按以下清单逐项完成,即可为新项目接入 CI/CD

# 步骤 操作位置 说明
1 创建 Harbor 项目 Harbor Web UI 项目名与代码仓库名一致
2 推送基础镜像 外网机器 将 Dockerfile 中用到的基础镜像推送到 library
3 编写 Dockerfile 代码仓库 使用内网基础镜像地址
4 编写 .drone.yml 代码仓库根目录 参考上方模板
5 激活 Drone 仓库 Drone Web UI 点击 Activate
6 配置 Drone Secrets Drone Web UI 添加 harbor / ssh 凭证
7 创建部署目录 部署服务器 /disk/docker-compose/{项目名}
8 编写 docker-compose.yml 部署服务器 配置镜像、端口、环境变量
9 配置 insecure-registries 部署服务器 Docker daemon 信任 Harbor
10 推送代码触发 代码仓库 push 到 master 分支

九、常见问题

Q: 构建时拉取基础镜像失败?

基础镜像需要提前推送到内网 Harbor。Drone Runner 的 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

Q: 如何回滚到指定版本?

使用 commit SHA 标签:

cd /disk/docker-compose/my-project

# 修改 docker-compose.yml 中的镜像标签
# 将 :latest 改为 :a1b2c3d4对应 commit SHA 前8位
# 然后重新部署
docker compose up -d

Q: 如何手动触发构建?

在 Drone 界面找到对应仓库,点击 New Build,选择分支即可。

Q: 如何只部署不重新构建?

直接在服务器上操作:

cd /disk/docker-compose/my-project
docker compose pull
docker compose up -d

Q: 构建步骤超时?

.drone.yml 的 step 中添加超时配置Drone 默认 60 分钟):

  - name: build
    image: plugins/docker
    settings:
      # ...
    # Drone 2.x 不直接支持 step 级别 timeout
    # 可在仓库设置中调整全局超时时间

Q: 如何查看构建日志?

访问 Drone CI 界面 http://192.168.195.25:13080,找到对应仓库和构建编号,点击查看每个步骤的日志。