Drone CICD自动化部署指南
一、Drone核心优势与架构设计
1.1 为什么选择Drone
Drone作为轻量级云原生CI/CD工具,相比Jenkins具有显著优势:
资源占用低:基于Docker容器化运行,单个Pipeline平均内存消耗<100MB
云原生支持:原生集成Kubernetes、Docker等云原生技术栈
配置即代码:完全通过.drone.yml定义流程,版本可控
高性能:测试显示并发构建能力比Jenkins高3-5倍16
1.2 企业级架构设计
[Gitee/GitHub] → [Drone Server] → [Docker Runner] (开发环境)
↘ [K8s Runner] (生产环境)
↘ [SSH Runner] (特殊场景)
二、 注册 OAuth 应用 (Gitee为例)
登录 Gitee → 点击右上角头像 → 设置 → 第三方应用 → 创建应用
填写应用信息:
- 应用名称:
Drone CI(自定义) - 应用描述:
Drone CI/CD 工具(自定义) - 授权回调地址:
http://你的服务器IP或域名/login(必须正确,否则无法登录) - 应用主页:
http://你的服务器IP或域名 - 权限选择:(最少权限原则)user_info,projects,pull_requests,hooks
- 应用名称:
提交后,记录生成的 Client ID 和 Client Secret(后续配置需要)
三、安装 Drone 服务器和 Runner
Drone 由两部分组成:
- Drone Server:管理项目、接收仓库事件、协调任务
- Drone Runner:执行流水线任务(编译、测试、部署等)
3.1 手动启动 Drone Server
docker run -d \
--name drone-server \
--restart always \
-p 80:80 \ # 端口映射(生产环境建议加 HTTPS)
-v /var/lib/drone:/data \ # 数据持久化
-e DRONE_RPC_SECRET=your_agent_secret \ # 自定义密钥(与 Runner 保持一致)
-e DRONE_GITEE_CLIENT_ID=你的Gitee Client ID \ # 替换为 Gitee 应用的 Client ID
-e DRONE_GITEE_CLIENT_SECRET=你的Gitee Client Secret \ # 替换为 Gitee 应用的 Secret
-e DRONE_GITEE_SERVER=https://gitee.com \ # Gitee 服务器地址(固定)
-e DRONE_SERVER_HOST=你的服务器IP或域名 \ # Drone 访问地址(如 drone.example.com)
-e DRONE_SERVER_PROTO=http \ # 协议(http 或 https)
-e DRONE_USER_CREATE=username:你的Gitee用户名,admin:true \ # 设置 Gitee 用户名作为管理员
drone/drone:2.16
DRONE_AGENT_SECRET 可以简单用命令生成openssl rand -hex 16
Drone Server 默认监听容器内的 80 端口(HTTP)和 443 端口(HTTPS,若配置证书),你可以通过 Docker 的端口映射映射(-p 参数)自定义宿主机的端口。
3.2 手动启动 Drone Runner
docker run -d \
--name drone-runner \
--restart always \
-v /var/run/docker.sock:/var/run/docker.sock \ # 必须挂载,允许操作 Docker
-e DRONE_RUNNER_NAME=my-gitee-runner \ # Runner 名称(自定义)
-e DRONE_RUNNER_CAPACITY=2 \ # 最大并行任务数
-e DRONE_RPC_SECRET=your_agent_secret \ # 与 Server 的密钥一致
-e DRONE_RPC_HOST=你的服务器IP或域名 \
-e DRONE_RPC_PROTO=http \
drone/drone-runner-docker:1.8
3.3 验证安装
docker ps | grep drone
# 若 drone-server 和 drone-runner 状态为 Up,则启动成功。
访问控制台:
打开浏览器访问 http://你的服务器IP:端口,会出现Drone页面,点击CONTINUE。首次登录需授权 Drone 访问你的 Gitee 账号和仓库,授权后即可进入控制台。
四、 激活项目、配置项目秘钥
成功打开 Drone 控制台后,接下来的核心操作是激活项目、配置流水线和管理构建任务。以下是详细步骤:
4.1 激活代码仓库(首次使用)
Drone 需与你的 Gitee 仓库关联才能触发流水线,需先「激活」项目:
- 进入 Drone 控制台首页
- 登录后,会显示你 Gitee 账号下的所有仓库列表(根据 OAuth 权限获取)。
- 激活目标项目
- 找到你需要配置 CI/CD 的仓库(例如 my-app),点击仓库卡片右侧的 ACTIVATE 按钮并Trusted
- 激活后,Drone 会自动为该仓库添加 Webhook(用于监听代码推送、PR 等事件),后续代码变动会自动触发流水线。
4.2 配置项目密钥(可选,用于部署等敏感操作)
如果你的流水线需要访问敏感信息(如服务器 SSH 密钥、数据库密码),需在 Drone 中配置「密钥」(Secrets),避免明文暴露:
- 进入项目设置:
- 点击已激活的项目 → 右上角 Settings(齿轮图标)。
- 添加密钥:这些密钥可在流水线配置文件(.drone.yml)中通过 from_secret: 密钥名 引用。
- 在 Secrets 区域,点击 Add Secret。
- 填写 Name(如 server_ssh_key)和 Value(如实际的 SSH 私钥内容)。
- 点击 Save 保存。
五、 编写流水线配置文件(核心)
在你的代码仓库根目录创建 .drone.yml 文件,定义自动化流程(如测试、编译、部署)。
示例(Golang 项目):
# 定义流水线类型和名称
kind: pipeline
type: docker
name: golang-enterprise-cd
# 触发条件:仅在 main 分支和 release/* 分支推送时执行
trigger:
branch:
- main
- release/*
event:
- push
- tag # 支持标签触发(如发布版本时)
# 工作空间配置:缓存依赖,加速构建
workspace:
path: /go/src/github.com/your-org/your-golang-project # 项目路径(根据实际调整)
# 流水线步骤
steps:
# 步骤1:代码质量检查(静态分析)
- name: code-quality
image: golangci/golangci-lint:v1.54-alpine # 代码检查工具
commands:
- golangci-lint run ./... # 运行所有代码检查规则
depends_on: [ ] # 无依赖,最先执行
# 步骤2:下载依赖并缓存
- name: fetch-dependencies
image: golang:1.21-alpine
commands:
- go mod tidy # 整理依赖
- go mod vendor # 导出依赖到vendor目录(便于缓存)
volumes:
- name: go-mod-cache # 挂载缓存卷
path: /go/pkg/mod
depends_on: [ code-quality ] # 依赖代码检查步骤
# 步骤3:单元测试并生成覆盖率报告
- name: unit-test
image: golang:1.21-alpine
commands:
- go test -v -race -coverprofile=coverage.out ./... # 运行测试(含数据竞争检测)
- go tool cover -func=coverage.out # 输出覆盖率摘要
volumes:
- name: go-mod-cache
path: /go/pkg/mod
depends_on: [ fetch-dependencies ]
# 步骤4:编译(分环境构建)
- name: build
image: golang:1.21-alpine
commands:
# 编译Linux版本(生产环境)
- CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X main.version=${DRONE_TAG:-latest}" -o app-linux ./cmd/server
# 编译Windows版本(可选,用于跨平台发布)
- CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-s -w -X main.version=${DRONE_TAG:-latest}" -o app-windows.exe ./cmd/server
# 查看编译产物
- ls -lh app-linux app-windows.exe
volumes:
- name: go-mod-cache
path: /go/pkg/mod
depends_on: [ unit-test ]
when:
event: [ push, tag ] # 推送和标签事件都执行
# 步骤5:构建Docker镜像(生产环境)
- name: build-docker
image: docker:24.0.5
commands:
# 登录Docker仓库(如私有仓库或Docker Hub)
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
# 构建镜像(标签包含Git commit和版本号)
- docker build -t your-registry/your-golang-app:${DRONE_TAG:-$DRONE_COMMIT} -t your-registry/your-golang-app:latest .
# 推送镜像
- docker push your-registry/your-golang-app:${DRONE_TAG:-$DRONE_COMMIT}
- docker push your-registry/your-golang-app:latest
volumes:
- name: docker-sock # 挂载Docker套接字
path: /var/run/docker.sock
environment:
DOCKER_USERNAME:
from_secret: docker_username # Docker仓库用户名(从密钥获取)
DOCKER_PASSWORD:
from_secret: docker_password # Docker仓库密码(从密钥获取)
depends_on: [ build ]
when:
branch: [ main ] # 仅主分支构建Docker镜像
# 步骤6:部署到生产环境(通过SSH)
- name: deploy-production
image: appleboy/drone-ssh
settings:
host:
from_secret: prod_server_host # 生产服务器地址
username:
from_secret: prod_server_user # 服务器用户名
key:
from_secret: prod_server_ssh_key # SSH私钥
port: 22
script:
# 切换到部署目录
- cd /opt/your-golang-app
# 拉取最新镜像
- docker pull your-registry/your-golang-app:${DRONE_TAG:-$DRONE_COMMIT}
# 停止旧容器
- docker-compose down || true
# 启动新容器(使用docker-compose管理)
- docker-compose up -d
# 检查服务状态
- docker-compose ps
depends_on: [ build-docker ]
when:
branch: [ main ] # 仅主分支部署到生产环境
event: [ push, tag ]
# 步骤7:发送构建结果通知(钉钉/企业微信)
- name: send-notification
image: appleboy/drone-webhook
settings:
urls:
from_secret: notification_webhook # 通知Webhook地址
content_type: application/json
body: |
{
"msgtype": "text",
"text": {
"content": "Golang项目构建结果:${DRONE_BUILD_STATUS}\n项目:${DRONE_REPO_NAME}\n分支:${DRONE_BRANCH}\n构建链接:${DRONE_BUILD_LINK}"
}
}
when:
status: [ success, failure ] # 成功或失败都通知
depends_on: [ deploy-production ]
# 定义缓存卷(加速构建)
volumes:
- name: go-mod-cache
temp: { } # 临时缓存(也可使用持久化卷)
- name: docker-sock
host:
path: /var/run/docker.sock # 挂载宿主机Docker套接字
示例 (PHP 项目):
# 定义流水线类型和名称
kind: pipeline
type: docker
name: php-enterprise-cd
# 触发条件:主分支、开发分支和标签事件
trigger:
branch:
- main
- develop
- feature/*
event:
- push
- pull_request
- tag
# 工作空间配置
workspace:
path: /var/www/html # PHP项目默认工作目录
# 流水线步骤
steps:
# 步骤1:代码风格检查(PHP_CodeSniffer)
- name: code-style
image: php:8.2-cli-alpine
commands:
# 安装代码检查工具
- curl -L https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar -o phpcs
- chmod +x phpcs
# 检查代码规范(使用PSR-12标准)
- ./phpcs --standard=PSR12 src/ tests/
depends_on: [ ]
# 步骤2:安装PHP依赖(Composer)
- name: install-dependencies
image: composer:2.5-alpine
commands:
- composer install --no-dev --optimize-autoloader # 生产环境依赖(无dev包)
- composer dump-autoload -o # 优化自动加载
volumes:
- name: composer-cache # 缓存Composer依赖
path: /tmp/composer-cache
depends_on: [ code-style ]
# 步骤3:单元测试(PHPUnit)
- name: unit-test
image: php:8.2-cli-alpine
commands:
# 安装PHP扩展和测试工具
- docker-php-ext-install pdo_mysql
- composer install # 安装开发依赖(含PHPUnit)
# 运行测试并生成报告
- vendor/bin/phpunit --coverage-text --configuration phpunit.xml
depends_on: [ install-dependencies ]
when:
event: [ pull_request, push ] # PR和推送时执行测试
# 步骤4:静态代码分析(PHPStan)
- name: static-analysis
image: php:8.2-cli-alpine
commands:
- composer require --dev phpstan/phpstan # 安装分析工具
- vendor/bin/phpstan analyse src/ --level=7 # 严格级别7(最高8)
depends_on: [ install-dependencies ]
# 步骤5:构建前端资源(若有Node.js依赖)
- name: build-frontend
image: node:18-alpine
commands:
- cd resources/assets # 进入前端资源目录
- npm install --production
- npm run build # 编译JS/CSS(如Webpack)
depends_on: [ static-analysis ]
when:
branch: [ main, develop ] # 仅主分支和开发分支构建前端
# 步骤6:构建Docker镜像(含Nginx+PHP-FPM)
- name: build-docker
image: docker:24.0.5
commands:
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
# 构建镜像(区分环境标签)
- |
if [ "$DRONE_BRANCH" = "main" ]; then
TAG="production-${DRONE_COMMIT:0:8}"
elif [ "$DRONE_BRANCH" = "develop" ]; then
TAG="staging-${DRONE_COMMIT:0:8}"
else
TAG="feature-${DRONE_BRANCH##*/}-${DRONE_COMMIT:0:8}"
fi
- docker build -t your-registry/your-php-app:$TAG .
- docker push your-registry/your-php-app:$TAG
volumes:
- name: docker-sock
path: /var/run/docker.sock
environment:
DOCKER_USERNAME:
from_secret: docker_username
DOCKER_PASSWORD:
from_secret: docker_password
depends_on: [ build-frontend ]
when:
event: [ push, tag ]
# 步骤7:部署到生产环境(使用Ansible自动化)
- name: deploy-production
image: williamyeh/ansible:alpine3
commands:
# 配置Ansible(连接生产服务器)
- mkdir -p ~/.ssh
- echo "$PROD_SSH_KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
- ansible-playbook -i ansible/inventory/prod.yml ansible/deploy.yml -e "image_tag=${TAG}"
environment:
PROD_SSH_KEY:
from_secret: prod_server_ssh_key
TAG: production-${DRONE_COMMIT:0:8}
depends_on: [ build-docker ]
when:
branch: [ main ]
event: [ push, tag ]
# 步骤8:部署到测试环境(开发分支)
- name: deploy-staging
image: appleboy/drone-ssh
settings:
host:
from_secret: staging_server_host
username:
from_secret: staging_server_user
key:
from_secret: staging_server_ssh_key
script:
- cd /opt/your-php-app
- docker-compose pull
- docker-compose up -d
depends_on: [ build-docker ]
when:
branch: [ develop ] # 开发分支部署到测试环境
# 步骤9:发送通知到企业微信
- name: notify
image: feiyu563/drone-wechat-work:latest
settings:
corp_id:
from_secret: wechat_corp_id
corp_secret:
from_secret: wechat_corp_secret
agent_id: 1000002
to_user: "@all"
message: "PHP项目构建${DRONE_BUILD_STATUS}\n仓库: ${DRONE_REPO}\n分支: ${DRONE_BRANCH}\n链接: ${DRONE_BUILD_LINK}"
when:
status: [ success, failure ]
# 缓存卷定义
volumes:
- name: composer-cache
host:
path: /tmp/composer-cache # 宿主机缓存目录(可持久化)
- name: docker-sock
host:
path: /var/run/docker.sock
六、 提交代码触发流水线
- 将 .drone.yml 提交到 Gitee 仓库:
git add .drone.yml git commit -m "Add Drone pipeline" git push origin main - 在 Drone 控制台查看流水线执行:
- 进入项目页面,会看到一条新的构建记录(状态为「running」),点击记录可查看实时日志:
- 绿色步骤表示成功,红色表示失败。
- 点击步骤名称可查看详细输出(如编译错误、测试结果)。
七、 管理构建任务
- 重新运行流水线:
- 若构建失败,可在构建记录页面点击 RESTART 重新运行,无需再次提交代码。
- 取消正在运行的任务:
- 点击构建记录页面的 STOP 按钮,终止当前流水线。
- 查看历史构建:
- 项目首页会显示所有历史构建记录,可按时间、状态筛选。
八 、其他操作(可选)
- 关闭项目自动触发:
- 若需临时禁用流水线,在项目 Settings 中关闭 Auto-cancel redundant builds 或直接 DEACTIVATE 项目(保留配置,不再监听事件)。
- 配置分支保护:
- 结合 Gitee 的分支保护规则,要求流水线成功后才能合并 PR(需在 Gitee 仓库设置中配置)。
- 集成通知:
- 在 .drone.yml 中添加邮件、钉钉、Slack 等通知步骤,例如构建失败时自动提醒:
- name: notify image: appleboy/drone-telegram settings: token: from_secret: telegram_token to: your_chat_id when: status: [success, failure] # 成功或失败都通知
- 在 .drone.yml 中添加邮件、钉钉、Slack 等通知步骤,例如构建失败时自动提醒:
通过以上步骤,即可利用 Drone 实现代码提交后的自动化测试、编译和部署。核心是通过 .drone.yml 定义流水线逻辑,Drone 会根据配置自动执行并反馈结果。