在微服务与容器化普及之后,传统的”在一台固定构建机上装一堆环境”的 CI 方式越来越难维护。Drone CI 是一款开源的容器原生 CI/CD 流水线引擎:每一条流水线步骤都在独立的 Docker 容器中执行,构建环境随用随起、用完即焚,天然解决了”在我机器上能跑”的环境漂移问题。本文从零带你用 Docker Compose 部署 Drone,编写 .drone.yml 流水线,并把它与 Jenkins、GitHub Actions 做选型对比,帮你判断它是否适合你的团队。
一、Drone 的核心设计:流水线即代码
Drone 的哲学非常简洁:流水线即 YAML 文件。你在仓库根目录放一个 .drone.yml,声明若干个步骤(step),每个 step 指定一个镜像和要执行的命令,Drone 就会按顺序把这些 step 跑成容器。它采用 Server + Runner 的分离架构:Server 负责 UI、仓库同步与任务调度,Runner 负责真正拉起容器执行流水线。这种设计带来三个直接收益。
第一,环境隔离。每一步都是全新容器,不会出现 A 项目装了 Python 3.8、B 项目需要 Python 3.11 互相覆盖的尴尬。第二,声明即文档。流水线定义和代码一起进版本库,新人 clone 下来就知道构建怎么跑。第三,扩展靠插件。发钉钉、推镜像、部署 SSH 等能力都由社区镜像提供,无需写复杂脚本。
对比在一台共享构建机上维护环境,Drone 的容器化思路几乎消灭了”环境雪崩”:你不必再为某个老项目锁死全局 Node 版本,也不必担心一次 apt upgrade 把别人的构建搞挂。每个 step 用的是镜像里写死的版本,可复现性从第一天就默认开启。对于同时要维护多个技术栈的团队,这一点比省下的机器成本更值钱。
二、快速起步:用 Docker Compose 部署 Drone
对于中小团队,最省心的方式是用 Docker Compose 把 Server 和 Runner 一起拉起来。Runner 这里选 drone-runner-docker,它会把每个流水线 step 作为容器执行。在此之前,你需要在一个 Git 平台(GitHub / Gitea / GitLab)创建 OAuth 应用,拿到 Client ID 和 Secret。如果你对容器编排还不熟,可以先复习一下后端服务容器化基础与Docker Compose 实战。
version: "3"
services:
drone-server:
image: drone/drone:2
ports:
- "127.0.0.1:8080:80"
environment:
- DRONE_GITEA_SERVER=https://gitea.example.com
- DRONE_GITEA_CLIENT_ID=your_client_id
- DRONE_GITEA_CLIENT_SECRET=your_client_secret
- DRONE_RPC_SECRET=super-secret-change-me
- DRONE_SERVER_HOST=ci.example.com
- DRONE_SERVER_PROTO=https
restart: always
drone-runner:
image: drone/drone-runner-docker:1
ports:
- "127.0.0.1:3000:3000"
environment:
- DRONE_RPC_PROTO=https
- DRONE_RPC_HOST=ci.example.com
- DRONE_RPC_SECRET=super-secret-change-me
- DRONE_RUNNER_CAPACITY=4
restart: always
其中 DRONE_RPC_SECRET 是 Server 与 Runner 之间的通信密钥,两边必须一致;DRONE_RUNNER_CAPACITY 表示 Runner 能并行执行的流水线数,按机器核数调整即可。启动后用 Nginx 反代 ci.example.com 到 8080 端口,登录授权后就能在仓库里激活 Drone。
三、编写第一条流水线:build → test → deploy
下面是一个典型的 Node 项目流水线:先装依赖跑单测,再构建镜像推到私有仓库,最后 SSH 到预发机拉起新版本。注意 Drone 默认会先 clone 代码,无需手写拉取步骤。
version: 1
kind: pipeline
type: docker
name: default
steps:
- name: 单元测试
image: node:20
commands:
- npm ci
- npm test
- name: 构建镜像
image: plugins/docker
settings:
repo: registry.example.com/app
tags: ${DRONE_COMMIT_SHA}
username:
from_secret: docker_user
password:
from_secret: docker_pass
- name: 部署到预发
image: appleboy/drone-ssh
settings:
host:
from_secret: staging_host
username: deploy
script:
- cd /opt/app && docker compose pull && docker compose up -d
when:
branch:
- main
plugins/docker 和 appleboy/drone-ssh 都是社区插件镜像,前者封装了镜像构建推送,后者通过 SSH 执行远程脚本。when.branch 让部署步骤只在 main 分支触发,feature 分支只会跑测试和构建,避免误发。
四、进阶能力
4.1 密钥与凭据管理
Drone 的 secret 是加密存储的,不会出现在日志里。推荐用 CLI 写入,CI 配置里用 from_secret 引用,而不是直接写明文。
drone secret add \
--repository example/app \
--name docker_pass \
--value "$DOCKER_PASSWORD" \
--conceal
4.2 缓存加速与矩阵构建
对依赖安装这类耗时步骤,可以用挂载卷做本地缓存,或用官方 cache 插件。需要跨多版本验证时,矩阵构建(matrix)能一次性铺开,比手写多条流水线清爽得多。
steps:
- name: 兼容性测试
image: node:${NODE_VERSION}
commands:
- npm ci
- npm test
matrix:
NODE_VERSION:
- "18"
- "20"
- "22"
五、Drone vs Jenkins vs GitHub Actions
选型时最常被拿来比较的是三者,差异主要在架构与运维成本上:
| 维度 | Drone CI | Jenkins | GitHub Actions |
|---|---|---|---|
| 架构 | Server+Runner,容器原生 | 单体 + 插件,JVM | 托管 SaaS,runner 可选自托管 |
| 学习曲线 | 低,YAML 即一切 | 高,概念与插件繁多 | 低,但自托管配置繁琐 |
| 自托管成本 | 极低,两个容器起 | 中,需维护 Master/节点 | 自托管 runner 需另搭 |
| 容器原生 | 原生,每步一个容器 | 需靠 Agent/镜像模拟 | 原生支持 |
| 生态 | 插件镜像生态较新 | 插件最丰富、最老牌 | Marketplace 丰富 |
如果你已经用 Jenkins 搭建了 CI/CD 流水线,并依赖大量老旧插件,迁移成本较高;轻量开源项目则可以直接用 GitHub Actions 免运维。Drone 的甜点区间是:需要自托管、想要极简声明式配置、又希望构建环境彻底干净的中小团队。
六、实战技巧
并行步骤:把互不依赖的测试与构建拆成独立 step,Drone 默认会并行执行同层级步骤,显著缩短流水线时长。
结果通知:用钉钉/Slack 插件在流水线结束时推送状态,失败第一时间告警。
依赖缓存:对于 node_modules、~/.m2 这类体积大又变动少的目录,推荐用官方 cache 插件做跨构建复用——把路径挂进缓存卷,命中时直接还原,能把动辄两三分钟的 npm ci 压到十几秒。配合矩阵构建,多个 Node 版本的依赖也能各自独立缓存、互不污染,既快又稳。
- name: 通知钉钉
image: guoxudongdocker/drone-dingtalk
settings:
token:
from_secret: dingtalk_token
message: "构建 ${DRONE_BUILD_STATUS}: ${DRONE_REPO_NAME}"
when:
status:
- success
- failure
对接 Kubernetes:如果你的集群已经用 Kustomize 管理部署清单,可以换用 Kubernetes Runner,把流水线 step 调度成 Pod 执行,弹性更好。只需把 pipeline 头部改成 type: kubernetes,其余 step 写法基本一致。结合 K8s HPA 自动扩缩容,能做到构建高峰自动扩容 Runner。
七、常见排障清单
| 现象 | 可能原因 | 排查动作 |
|---|---|---|
| Runner 一直 pending | RPC_SECRET 不一致 / Runner 未连上 Server | 核对两端密钥,看 Runner 日志连接状态 |
| 步骤报权限 denied | secret 未绑定到该仓库或拼写错 | 用 drone secret ls 核对名称 |
| 镜像拉取超时 | 私有仓库未配置 registry 凭据 | 在 Runner 环境加 DRONE_DOCKER_CONFIG |
| 流水线卡在某步 | 命令前台阻塞(如起了常驻进程) | 确保命令前台退出,或用 & 配合 wait |
八、结语
Drone CI 用”每个步骤一个容器”的极简思路,把 CI 环境的干净与可复现做到了极致。它没有 Jenkins 那样庞杂的插件体系,也不像纯 SaaS 那样把数据留在别人手里,恰好卡在自托管与轻量之间的黄金位置。如果你正打算给团队换一套清爽的流水线,不妨从 Docker Compose 拉起两个容器开始试一试。




