drone介绍
drone 无人机
Tip
刚接触时认为这东西很好用, 后来觉得设计上有些先天缺陷。
背景
先说几句闲话,docker这个概念刚出的时候,我其实已经关注到了。
大概在14年到15年时,我已经在非生产环境推行docker了,尝试将例如原来在使用 zabbix, nginx, tomcat, memcache等, 以及一些小的管理系统,还有一些工作中自己开发的python服务给容器化。
但之后几年时间反复前进后退,没有什么实质行的进展。
直到18-19年上云的大背景下,才集中一波将当时项目的生产环境的业务给容器化。
原因一直很清楚,就是上容器很简单,但是更新困难。
比如 python 程序,你发现有个字符串需要改, 原本直接 vi 编辑加 restart 即可;
现在却要提交代码,重新打镜像,上传,拉镜像,更新服务,步骤太繁琐啦。
为什么不自动化实现这些步骤呢?
原因是当时要实现这些,基本上只有两种方案,
- 写大量shell脚本
- jenkins
我以前写过很多 bash 脚本,几乎写吐,实在是不想写了,被里面各种特性,各种奇淫技巧,和隐藏的各种陷阱杀害了太多脑细胞。
而且很明显 bash 并不适合完成太大的流程。
然后就是 jenkins, 我从14年开始接触这个工具,直到今天我依然不喜欢,复杂+繁琐,我几乎每年都要重新学一遍,然后再忘一遍。
直到 drone 这个系统的出现,终于感觉有个好用 CI 工具的了。
drone 简介
- go 开发,意味着部署简单
- master+slave 结构,扩展方便
- 容器化,全程使用 docker 完成
- 插件支持友好
我个人认为最大的优点是 插件友好;
插件简介
- 一个插件就是一个容器,简介
- 插件无依赖关系,对离线环境极为友好; jenkins 的离线环境装更新插件就非常难处理依赖关系; 当然 jenkins 离线首次安装时插件可以直接拷贝进去,但后面再加就不好办了
- 插件支持 go 开发,也支持 sh 开发
- 无用户体系,直接使用 git 源的账户系统
- 编排文件 .drone 采用 yml 结构,比 Jenkis 的 Jenkinsfile 文件格式友好太多
而且可以很方便的看到部署流程图

缺点
有几个不得不说的注意事项
drone 分开源版本和企业版本; 开源版本需要自己编译生成二进制文件或镜像; 官方释放出来的包其实是企业版本的;
企业版本默认是有很多限制的, 但在特定情况下是可以免费使用的;
- 一年构建次数不超过 5000 次
- 企业年收入低于 100 万美元, 或融资少于 500 万美元
主要就这个限制, 超出后按协议需要付费;
个人使用的话,一般一年不会超出这个次数限制;
企业使用的话,其实影响也不大, 到次数前把库删除服务重新部署一份就是, 受影响的也就 保存的一些 secret 和 构建历史记录, 这些都好重建或干脆删除;
如果对这个商用协议很敏感的话,还有2个办法
- 通过开源版本自己编译一份
- 使用完全开源的 woodpecker(啄木鸟) 来平替 drone
使用方式
- 物理机方式 部署一个 server 和 一个以上 runner
- docker-compose 方式
- k8s 内部署方式
不同的部署方式影响一些插件的使用和 pipeline 的类型;
k8s环境使用事项
- 因为当前 k8s 环境没有使用 docker, 所以镜像打包用的是 google 的 kaniko 工具来打包
- 一个 pipeline 本质上就是一个 pod, 每个 step 实际上就是这个 pod 内的一个容器
- runner 因为要创建新的 pod, 所以需要 api 权限, 这里创建了 sa, 并绑定了创建 pod 的权限;
- 因为运行机器的不确定性, 所以编译缓存我们使用了一个 pvc 来单独放置
- 这里有使用 drone-k8s-plugin 插件发布 yml 资源文件到集群, 所以需要还需要一个 sa 帐号
部署
目前使用 docker-compose 的方式应该是主流的方式
docker-compose.yml
注解:
-
registry.wait 为离线的私有仓库,
git.services.wait 为离线的 gitea 仓库 -
用户 master 和 slave 通信的 DRONE_RPC_SECRET 是随便生成的;
-
Gitea OAuth 需要在 gitea 上配置一个应用和返回时的地址
-
特别注意的是 drone 没有账号体系,使用的是 gitea 里面的账号;
这里指定管理员时,需要指定 gitea 的用户登录帐号, 注意不是别名或邮箱地址。 -
本例使用了 traefik 作为统一的入口
-
存储和网络都是 external 类型的, 所以需要手动创建
version: '3'
services:
drone-server:
image: registry.wait/cwx/drone/drone:2.16.0
# ports:
# - 80:80
# - 443:443
restart: unless-stopped
networks:
- services
# privileged: true
environment:
# GITEA 配置(OAuth2)
# Gitea OAuth 客户端 ID
- DRONE_GITEA_CLIENT_ID=3dee43ca-55c2-4878-b912-5fe892cc6f4b
# Gitea OAuth 客户端密钥
- DRONE_GITEA_CLIENT_SECRET=gto_rkxuxkaneyrxpuji5i3hwvunhlzd3sfhhifhn4z5qj23u6hz2nu3
# Gitea 服务器地址
- DRONE_GITEA_SERVER=https://git.services.wait
# - DRONE_GITEA_SERVER=http://10.2.1.5:3000
# 和 runner 通信的 rpc 密钥
- DRONE_RPC_SECRET=12e42a821c41754db091b62d899edff7
# drone server 的服务地址; IP或域名
- DRONE_SERVER_HOST=drone.services.wait
# - DRONE_TLS_AUTOCERT=false
- DRONE_SERVER_PROTO=https
# - DRONE_SERVER_PROTO=https
# - DRONE_TLS_CERT=/certs/services.wait.pem
# - DRONE_TLS_KEY=/certs/services.wait-key.pem
- DRONE_LOGS_DEBUG=true
# - DRONE_GIT_ALWAYS_AUTH=false
# 创建管理员账户, 这里对应为 gitee 的用户名(也就是登录的账号,不是昵称)
# 也就是说 这个外部帐号会作为管理员
# 说明, 这里应该是 gitee 内的登录帐号, 不是别名或邮箱
- DRONE_USER_CREATE=username:chenwx,admin:true
# 数据库默认是 sqlite
# - DRONE_DATABASE_DRIVER=mysql
# - DRONE_DATABASE_DATASOURCE=root:password@tcp(1.2.3.4:3306)/drone?parseTime=true
volumes:
- drone_data:/data
# - ./ssl/services.wait.pem:/certs/services.wait.pem:ro
# - ./ssl/services.wait-key.pem:/certs/services.wait-key.pem:ro
- ./ssl/cwxCA.pem:/etc/ssl/certs/cwxCA.pem:ro
labels:
- "service_name=drone"
- "traefik.enable=true"
- "traefik.http.routers.droneHttps.entrypoints=https"
- "traefik.http.routers.droneHttps.service=droneServer"
- "traefik.http.routers.droneHttps.rule=Host(`drone.services.wait`)"
- "traefik.http.routers.droneHttps.tls=true"
- "traefik.http.services.droneServer.loadbalancer.server.port=80"
logging:
options:
labels: "service_name"
drone-docker-runner:
# container_name: drone-runner
image: registry.wait/cwx/drone/drone-runner-docker:1.8.3
# restart: always
# privileged: true
networks:
- services
environment:
# 用于连接到 Drone 服务器的协议; http 或 https
# - DRONE_RPC_PROTO=https
- DRONE_RPC_PROTO=https
# 用于连接到 Drone 服务器的主机名
- DRONE_RPC_HOST=drone.services.wait
# server rpc key
- DRONE_RPC_SECRET=12e42a821c41754db091b62d899edff7
# 限制运行程序可以执行的并发管道数
- DRONE_RUNNER_CAPACITY=2
# 自定义 docker runner 节点名称
- DRONE_RUNNER_NAME=docker-runner-1
# - DRONE_RUNNER_NETWORKS=drone_default
# - DRONE_DEBUG=true # 调试相关, 部署的时候建议先打开
# - DRONE_LOGS_DEBUG=true # 调试相关, 部署的时候建议先打开
# - DRONE_LOGS_TRACE=true # 调试相关, 部署的时候建议先打开
- TZ=Asia/Shanghai
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/wait/data/ca/cwxCA.pem:/etc/ssl/certs/cwxCA.pem:ro
volumes:
drone_data:
external: true
networks:
services:
external: true项目实例
实例1: nodejs 项目
.drone.yml 文件示例
注解:
- 需要在 ui 页面上配置2个 secrets 密钥;
dockerconfigjson 是私有 docker 仓库的配置,
wcn7_wait_key 是目标 ssh 主机的ssh密钥。 - 离线部署时,可以先将需要的镜像都上传到私有镜像仓库,
本例 registry.wait 即内部仓库地址 - drone-volume-cache 目的是将 node_modules 内容进行缓存和加载,避免反复拉取;
- http://10.2.1.5:4873/ 这个地址是私有化的 node 仓库
- gitea-release 插件的目的是在 tag 编译后,将 release 发布到仓库
- 效果就是普通的提交,走普通流程,发布到测试环境;
带 tag 的提交走新流程, 发布 release 到 gitea 仓库。
kind: pipeline
name: ctools
type: docker
# 私有镜像站认证信息
image_pull_secrets:
- dockerconfigjson
# 因为有个性化的 clone 需求,所以这里关闭默认的 clone 动作
clone:
disable: true
steps:
- name: 克隆仓库
# image: drone/git
image: registry.wait/cwx/drone/git
pull: if-not-exists
settings:
# clone 时截断以前的提交记录, 即克隆深度
depth: 1
skip_verify: true
# 读取 git 的 tag 作为环境变量 ${DRONE_TAG}
tags: true
# 因为没能解析到名字,临时加一下 hosts
# extra_hosts:
# - "git.services.wait:10.2.1.5"
commands:
- git config --global http.sslVerify false
- git clone https://git.services.wait/chenwx/ctools.git .
- ls -a
- git log --oneline -n 5
# 使用缓存避免反复从网络上下载依赖包
# - name: restore-cache
- name: 加载编译缓存
image: registry.wait/cwx/drone/drillster/drone-volume-cache
# image: drillster/drone-volume-cache
# 默认各阶段是并行处理的, 需要定义依赖关系
depends_on: [克隆仓库]
volumes:
- name: cache
path: /cache
settings:
# 从以前的构建中恢复缓存,即拷贝这个目录下的内容到容器内
restore: true
mount:
- ./node_modules
# - name: build
- name: 开发环境-编译
# image: node:19.9.0
image: registry.wait/cwx/node:19.9.0
pull: if-not-exists
depends_on: [加载编译缓存]
commands:
- ls -a
- node -v
- npm get registry
- npm config set registry http://10.2.1.5:4873/
- npm install
- npm run build
- cd dist
- tar zcvf ctools-0.1.tar.gz ./*
# 排除全部tag,即不匹配任何 tag
when:
ref:
exclude:
- refs/tags/**
# 具有 tag 时的编译动作
# - name: build-tag
- name: 生产环境-编译
# image: node:19.9.0
image: registry.wait/cwx/node:19.9.0
pull: if-not-exists
depends_on: [加载编译缓存]
commands:
- ls -a
- node -v
- npm install
- npm run build
- cd dist
- tar zcvf ctools-${DRONE_TAG##v}.tar.gz ./*
- ls
# 匹配全部tag
when:
ref:
- refs/tags/**
# 将缓存文件卸载
# - name: rebuild-cache
- name: 开发环境-卸载缓存
image: registry.wait/cwx/drone/drillster/drone-volume-cache
# image: drillster/drone-volume-cache
pull: if-not-exists
depends_on: [开发环境-编译]
volumes:
- name: cache
path: /cache
settings:
# 重新创建缓存, 即将文件写回到宿主机
rebuild: true
mount:
- ./node_modules
when:
ref:
exclude:
- refs/tags/**
# 为有 tag 的情况
# - name: rebuild-cache-tag
- name: 生产环境-卸载缓存
# image: drillster/drone-volume-cache
image: registry.wait/cwx/drone/drillster/drone-volume-cache
pull: if-not-exists
depends_on: [生产环境-编译]
volumes:
- name: cache
path: /cache
settings:
rebuild: true
mount:
- ./node_modules
when:
ref:
- refs/tags/**
# 提交一个 release 版本到 gitea
# gitea-release 插件只适用于有 tag 的情况
# - name: gitea_release
- name: 生产环境-gitea-release
# image: plugins/gitea-release
image: registry.wait/cwx/drone/plugins/gitea-release
pull: if-not-exists
depends_on: [生产环境-编译]
settings:
api_key: 2a5ab57061a66a6f37233a3fac07029cb5ad6b76
base_url: https://git.services.wait/
files:
# 上传文件时,把那个 v 前缀去掉
- dist/ctools-${DRONE_TAG##v}.tar.gz
# 如果存在则覆盖
file_exists: overwrite
title: 新版本发布-${DRONE_TAG}
# 忽略 https 证书
insecure: true
volumes:
- name: cwxCA
path: /etc/ssl/certs/ca-certificates.crt
# extra_hosts:
# - "git.services.wait:10.2.1.5"
when:
ref:
- refs/tags/**
# 使用 scp 传输到其它主机
# - name: deployment
- name: 开发环境-推送
# image: appleboy/drone-scp
image: registry.wait/cwx/drone/appleboy/drone-scp
pull: if-not-exists
depends_on: [开发环境-编译]
settings:
host: 10.2.1.5
username: wait
# password:
# # 密码使用单独存储在 drone 上的密码
# from_secret: wcn7_wait_pw
key:
from_secret: wcn7_wait_key
port: 22
# 目标: /home/wait/chenwx/ctools/ctools-0.1.tar.gz
target: /home/wait/${DRONE_REPO_OWNER}/${DRONE_REPO_NAME}
source: dist/ctools-0.1.tar.gz
when:
ref:
exclude:
- refs/tags/**
# 推送到生产环境
# - name: deployment-production
- name: 生产环境-推送
# image: appleboy/drone-scp
image: registry.wait/cwx/drone/appleboy/drone-scp
pull: if-not-exists
depends_on: [生产环境-编译]
settings:
host: 10.3.0.2
username: wait
key:
from_secret: wcn7_wait_key
port: 39022
# 目标: /home/wait/data/pkg/ctools-0.1.tar.gz
target: /home/wait/data/pkg
source: dist/ctools-${DRONE_TAG##v}.tar.gz
when:
ref:
- refs/tags/**
# 到远程主机执行命令
# - name: ssh
- name: 开发环境-部署
# image: appleboy/drone-ssh
image: registry.wait/cwx/drone/appleboy/drone-ssh
pull: if-not-exists
depends_on: [开发环境-推送]
settings:
host:
- 10.2.1.5
username: wait
# password:
# from_secret: wcn7_wait_pw
key:
from_secret: wcn7_wait_key
port: 22
command_timeout: 1m
script:
- cd /home/wait/chenwx/ctools
- rm -rf tmp2 && mkdir tmp2
- tar xvf dist/ctools-0.1.tar.gz -C tmp2/
- rm -rf /home/wait/data/tools/*
- mv tmp2/* /home/wait/data/tools/
when:
ref:
exclude:
- refs/tags/**
# 生产环境-部署命令
# - name: ssh-production
- name: 生产环境-部署
# image: appleboy/drone-ssh
image: registry.wait/cwx/drone/appleboy/drone-ssh
pull: if-not-exists
depends_on: [生产环境-推送]
settings:
host:
- 10.3.0.2
username: wait
key:
from_secret: wcn7_wait_key
port: 39022
command_timeout: 1m
script:
- cd /home/wait/data/pkg
- rm -rf tmp2 && mkdir tmp2
- tar xvf dist/ctools-${DRONE_TAG##v}.tar.gz -C tmp2/
- rm -rf /home/wait/data/tools/*
- mv tmp2/* /home/wait/data/tools/
when:
ref:
- refs/tags/**
volumes:
- name: cache
host:
path: /data/cache
- name: cwxCA
host:
path: /home/wait/data/ca/cwxCA.pem
# path: /home/wait/code/ssl/ca/cwxCA.pem开发环境发布
git push

生产环境发布
git tag v0.0.9
git push origin v0.0.9

实例2: go项目示例
调试截图

**成功流程

完整清单
kind: pipeline
type: kubernetes
name: cwxgoweb-dev
service_account_name: drone
clone:
disable: true
# main 分支 + push
trigger:
branch:
- main
event:
- push
volumes:
- name: gopath-cache
claim:
name: gobuild-cache
read_only: false
steps:
- name: 启动无人机
image: registry.services.wait/cwx/os/alpine:3.18.3
commands:
- echo "测试启动 drone 成功"
- name: 克隆仓库
image: registry.services.wait/cwx/drone/git
pull: if-not-exists
depends_on: [启动无人机]
settings:
# clone 时截断以前的提交记录, 即克隆深度
depth: 1
skip_verify: true
# 读取 git 的 tag 作为环境变量 ${DRONE_TAG}
tags: true
environment:
GITEA_TOKEN:
from_secret: git_token
commands:
- git config --global http.sslVerify false
# 通过 token 拉取代码
- git clone https://chenwx:$GITEA_TOKEN@git.services.wait/chenwx/cwxgoweb.git .
# 输出最近 5 次 commit 信息
- git log --oneline -n 5
- pwd
- ls -a
- name: 编译
image: registry.services.wait/cwx/golang:1.21.0
pull: if-not-exists
depends_on: [克隆仓库]
# 挂载编译缓存
volumes:
- name: gopath-cache
path: /go
commands:
- go env -w GOPROXY=http://nexus.services.wait/repository/proxy-go/
- go env -w GOSUMDB=off
- export CGO_ENABLED=0
- go build -o cwxgoweb src/main.go
# - go build -o cwxgoweb -ldflags '-s -w' src/main.go
- ls -a
# 制作镜像
- name: 生成镜像
image: registry.services.wait/cwx/kaniko-project/executor:v1.15.0-debug
pull: if-not-exists
depends_on: [ 编译 ]
environment:
CA_CERTIFICATE:
from_secret: ca_wait
DOCKER_AUTH_FILE:
from_secret: docker_user_wait_conf
commands:
# 一张内部的CA证书
- echo "$CA_CERTIFICATE" >> /kaniko/ssl/certs/additional-ca-cert-bundle.crt
# docker 仓库认证文件 .docker/config.json
- echo $DOCKER_AUTH_FILE > /kaniko/.docker/config.json
- /kaniko/executor
--context "."
--dockerfile "deploy/docker/drone/dockerfile"
--destination "registry.services.wait/cwx/cwxgoweb:latest"
# 发布k8s集群
- name: deploy
image: registry.services.wait/cwx/zc2638/drone-k8s-plugin:0.0.4
pull: if-not-exists
depends_on: [ 克隆仓库 ]
settings:
k8s_server: https://kubernetes.default.svc.cluster.local
k8s_token:
from_secret: k8s_token
k8s_ca_crt:
from_secret: k8s_ca_crt
k8s_skip_tls: false
namespace: cwx
templates:
- deploy/kubernetes/devel/deployment.yml
- deploy/kubernetes/devel/IngressRoute.yml
- deploy/kubernetes/devel/services.yml
# app_name: ${DRONE_REPO_NAME}
debug: true
---
# 流水线2
# 生产环境打包, 只对带 tag 的事件触发执行
kind: pipeline
type: kubernetes
name: cwxgoweb-pro
service_account_name: drone
# 触发器这里 tag 不能和分支一起使用, 因为 tag 和 分支是没有关系的
trigger:
event:
- tag
volumes:
- name: gobuild-cache
claim:
name: gobuild-cache
read_only: false
# 因为有个性化的 clone 需求, 所以这里关闭默认的 clone 动作
clone:
disable: true
steps:
- name: 克隆仓库
image: registry.services.wait/cwx/drone/git
pull: if-not-exists
settings:
depth: 1
skip_verify: true
tags: true
environment:
GITEA_TOKEN:
from_secret: git_token
# 注意为了避免 tag 比 main 分支先提交的情况
# 这里需要固定拉取 此 tag
commands:
- git config --global http.sslVerify false
- git clone -b ${DRONE_TAG} --depth=1 https://chenwx:$GITEA_TOKEN@git.services.wait/chenwx/cwxgoweb.git .
- pwd
- ls -a
- name: 编译
image: registry.services.wait/cwx/golang:1.21.0
pull: if-not-exists
depends_on: [克隆仓库]
volumes:
- name: gopath-cache
path: /go
commands:
# - go env -w GOPROXY=http://10.2.1.4:8081/repository/group-go/
- go env -w GOPROXY=http://nexus.services.wait/repository/proxy-go/
- go env -w GOSUMDB=off
- export CGO_ENABLED=0
- go build -o cwxgoweb src/main.go
# - go build -o cwxgoweb -ldflags '-s -w' src/main.go
- ls -a
# 有 tag 时, 制作一个 压缩包,后续上传到 release
- name: 打包
image: registry.services.wait/cwx/os/alpine:3.18.3
depends_on: [ 编译 ]
commands:
- ls -a
- tar zcvf cwxgoweb-${DRONE_TAG}.tar.gz ./cwxgoweb
# 当生产环境打包完成后, 提交一个 release 版本到 gitea
# gitea-release 插件只适用于有 tag 的情况
- name: push-release
image: registry.services.wait/cwx/drone/plugins/gitea-release
pull: if-not-exists
depends_on: [ 打包 ]
environment:
GITEA_TOKEN:
from_secret: git_token
settings:
api_key: $GITEA_TOKEN
base_url: https://git.services.wait/
files:
- cwxgoweb-${DRONE_TAG}.tar.gz
# 如果存在则覆盖
file_exists: overwrite
title: 新版本发布 -${DRONE_TAG}
# 忽略 https 证书
insecure: true
# volumes:
# - name: cwxCA
# path: /etc/ssl/certs/ca-certificates.crt
# 制作镜像
- name: 生成镜像
image: registry.services.wait/cwx/kaniko-project/executor:v1.15.0-debug
pull: if-not-exists
depends_on: [ 编译 ]
environment:
CA_CERTIFICATE:
from_secret: ca_wait
DOCKER_AUTH_FILE:
from_secret: docker_user_wait_conf
commands:
# 一张内部的CA证书
- echo "$CA_CERTIFICATE" >> /kaniko/ssl/certs/additional-ca-cert-bundle.crt
# docker 仓库认证文件 .docker/config.json
- echo $DOCKER_AUTH_FILE > /kaniko/.docker/config.json
- /kaniko/executor
--context "."
--dockerfile "deploy/docker/drone/dockerfile"
--destination "registry.services.wait/cwx/cwxgoweb:${DRONE_TAG}"
# 发布k8s集群
- name: deploy
image: registry.services.wait/cwx/zc2638/drone-k8s-plugin:0.0.4
pull: if-not-exists
depends_on: [ 生成镜像 ]
settings:
k8s_server: https://kubernetes.default.svc.cluster.local
k8s_token:
from_secret: k8s_token
k8s_ca_crt:
from_secret: k8s_ca_crt
k8s_skip_tls: false
namespace: cwx
templates:
- deploy/kubernetes/prod/deployment.yml
- deploy/kubernetes/prod/IngressRoute.yml
- deploy/kubernetes/prod/services.yml
images_tags: ${DRONE_TAG}
debug: true实例3: go示例2
注解:
- 拉取代码后,进行编译
- 开发环境只是更新了远程主机的二进制文件,和生成了一个 docker 镜像
- 生产环境模拟做区分,推送一个 包 到 gitea 仓库
- 考虑不要用这个 docker 插件来打镜像,自己本地打似乎更好一些;
- 特别注意的是文件里面一些变量的引用方式很奇怪
kind: pipeline
name: nginx-log-go
type: docker
# 私有镜像站认证信息
image_pull_secrets:
- dockerconfigjson
# 因为有个性化的 clone 需求,所以这里关闭默认的 clone 动作
clone:
disable: true
steps:
- name: 克隆仓库
image: registry.wait/cwx/drone/git
pull: if-not-exists
settings:
# clone 时截断以前的提交记录, 即克隆深度
depth: 1
skip_verify: true
# 读取 git 的 tag 作为环境变量 ${DRONE_TAG}
tags: true
# 工作目录为 /drone/src
commands:
- git config --global http.sslVerify false
- git clone https://git.services.wait/chenwx/nginx-log-go.git .
- git log --oneline -n 5
- pwd
- ls -a
# - name: build
- name: 编译
image: registry.wait/cwx/golang:1.20.3
pull: if-not-exists
depends_on: [克隆仓库]
volumes:
- name: gopath-1.20.3
path: /go
commands:
- go env -w GOPROXY=https://goproxy.cn,direct
- export CGO_ENABLED=0
- go build -o bin/nginxLog -ldflags '-s -w' src/main.go
- ls bin
# 有 tag 时,制作一个 压缩包
- name: 生产环境-打包
image: registry.wait/cwx/os/alpine:3.17.3
depends_on: [编译]
commands:
- ls -a
- cd bin
- tar zcvf nginxLog-${DRONE_TAG##v}.tar.gz ./nginxLog
# 匹配全部tag
when:
ref:
- refs/tags/**
# 提交一个 release 版本到 gitea
# gitea-release 插件只适用于有 tag 的情况
- name: 生产环境-push-release
image: registry.wait/cwx/drone/plugins/gitea-release
pull: if-not-exists
depends_on: [生产环境-打包]
settings:
api_key: 2a5ab57061a66a6f37233a3fac07029cb5ad6b76
base_url: https://git.services.wait/
files:
# 上传文件时,把那个 v 前缀去掉
- bin/nginxLog-${DRONE_TAG##v}.tar.gz
# 如果存在则覆盖
file_exists: overwrite
title: 新版本发布-${DRONE_TAG}
# 忽略 https 证书
insecure: true
volumes:
- name: cwxCA
path: /etc/ssl/certs/ca-certificates.crt
when:
ref:
- refs/tags/**
# 使用 scp 传输到其它主机
- name: 开发环境-推送
image: registry.wait/cwx/drone/appleboy/drone-scp
pull: if-not-exists
depends_on: [编译]
settings:
host: 10.2.1.5
username: wait
key:
from_secret: wcn7_wait_key
port: 22
target: /home/wait/data/pkg/${DRONE_REPO_NAME}
source: bin/nginxLog
when:
ref:
exclude:
- refs/tags/**
# 到远程主机执行命令
- name: 开发环境-部署
image: registry.wait/cwx/drone/appleboy/drone-ssh
pull: if-not-exists
depends_on: [开发环境-推送]
settings:
host:
- 10.2.1.5
username: wait
key:
from_secret: wcn7_wait_key
port: 22
command_timeout: 1m
script:
- cd /home/wait/data/pkg/${DRONE_REPO_NAME}
- rm -f /home/wait/bin/nginxLog
- mv bin/nginxLog /home/wait/bin/
when:
ref:
exclude:
- refs/tags/**
# 制作镜像
# 存在的问题,虽然插件最后有清理容器的动作,但没有实际执行成功
- name: 生成镜像
image: registry.wait/cwx/plugins/docker:20.14.2
pull: if-not-exists
depends_on: [编译]
settings:
registry: registry.wait
repo: registry.wait/cwx/nginx-log-go # 私有仓库
tags:
- dev
no_cache: true
# 自动分割 git tag 的标签
# auto_tag: true
dockerfile: dockerfile
# 允许不安全的通信, 实际测试没生效,还是得挂证书
# insecure: true
username:
from_secret: docker_registry_username
password:
from_secret: docker_registry_password
volumes:
- name: cwxCA
path: /etc/ssl/certs/ca-certificates.crt
- name: docker
path: /var/run/docker.sock
# 制作镜像
# 此处采用 docker in docker 的方式目的是不想二次生成镜像
- name: 生产环境-生成镜像
image: registry.wait/cwx/docker:23.0.4
pull: if-not-exists
depends_on: [生成镜像]
volumes:
- name: docker
path: /var/run/docker.sock
- name: docker_configjson
path: /root/.docker/config.json
environment:
IMG_NAME: registry.wait/cwx/nginx-log-go
# USERNAME:
# from_secret: docker_registry_username
# PASSWORD:
# from_secret: docker_registry_password
commands:
- echo $TAG_NAME
- echo ${TAG_NAME}
- "docker tag $IMG_NAME:dev $IMG_NAME:${DRONE_TAG##v}"
- "docker push $IMG_NAME:${DRONE_TAG##v}"
# - docker login -u $USERNAME -p $PASSWORD registry.wait
# - docker tag $IMG_NAME:dev $IMG_NAME:${DRONE_TAG##v}
# - docker push $IMG_NAME:${DRONE_TAG##v}
when:
ref:
- refs/tags/**
# 生产环境-部署命令
- name: 生产环境-部署
image: registry.wait/cwx/drone/appleboy/drone-ssh
pull: if-not-exists
depends_on: [生产环境-生成镜像]
settings:
host:
- 10.2.1.5
port: 22
username: wait
key:
from_secret: wcn7_wait_key
command_timeout: 1m
script:
- cd /home/wait/env_docker/nodes/wcn7/service
- sed -i "/registry.wait\\/cwx\\/nginx-log-go/s/nginx-log-go:.*$/nginx-log-go:${DRONE_TAG##v}/" docker-compose.yml
- docker compose up nginx-log-go -d
when:
ref:
- refs/tags/**
volumes:
- name: gopath-1.20.3
host:
path: /data/cache/gopath-1.20.3
- name: cwxCA
host:
path: /home/wait/data/ca/cwxCA.pem
- name: docker
host:
path: /var/run/docker.sock
- name: docker_configjson
host:
path: /home/wait/.docker/config.json
实例4: 当前站点的发布实践
看起来还有很多改进的空间, 但是我后来发现了 gitea-runner 这一套了, 就不再想用 drone 了。 回头看我还是很喜欢的 drone 的纯容器模式。使用 runner 不得不接触大量的 js,虽然不复杂,但也挺麻烦的。
.drone.yml 文件
kind: pipeline
type: kubernetes
name: myblog
service_account_name: drone
# 因为有个性化的 git 需求, 所以这里禁用默认的 clone
clone:
disable: true
# 触发器
trigger:
event:
- push
steps:
- name: 克隆仓库
image: registry.services.wait/cwx/drone/git
pull: if-not-exists
settings:
depth: 1
skip_verify: true
tags: true
environment:
GITEA_TOKEN:
from_secret: git_token
commands:
- git config --global http.sslVerify false
- git clone https://chenwx:$GITEA_TOKEN@git.services.wait/chenwx/myblog.git .
- git clone https://chenwx:$GITEA_TOKEN@git.services.wait/chenwx/hugo-theme-stack.git themes/hugo-theme-stack
- name: 编译
image: registry.services.wait/cwx/hugo:ubuntu-v0.118
pull: if-not-exists
depends_on: [克隆仓库]
commands:
- hugo
- tar zcvf myblog.tar.gz -C public/ .
- name: 推送
image: registry.services.wait/cwx/drone/appleboy/drone-scp
pull: if-not-exists
depends_on: [ 编译 ]
settings:
host: 10.2.1.5
username: wait
key:
from_secret: wait_ssh_key
port: 22
source: myblog.tar.gz
target: /tmp/
- name: deplay
image: registry.services.wait/cwx/drone/appleboy/drone-ssh
pull: if-not-exists
depends_on: [ 推送 ]
settings:
host:
- 10.2.1.5
username: wait
key:
from_secret: wait_ssh_key
port: 22
command_timeout: 1m
script:
- rm -rf /data/nfs_private/blog-web-data/blog/*
- tar xf /tmp/myblog.tar.gz -C /data/nfs_private/blog-web-data/blog/
- rm -f /tmp/myblog.tar.gz