Drone 入门指引
最近在尝试用 Drone 替换动辄占用上 G 内存的 jenkins,决定把初步成果分享出来,本文会提供搭配 Gitea 的一个前端和一个 golang 项目的配置样例。
安装
安装非常简单,按照官方给的样例写好 docker-compose.yml 启动即可:
| 1 | services: | 
其中 .env 的文件内容为:
| 1 | DRONE_HOST=ci.yourdomain.com # drone 访问域名 | 
当然还有现成的 gitea 或者其他 git 服务。
下载官方提供的二进制文件提供命令操作功能 http://docs.drone.io/cli-installation/
搭配 gitea 的方案可以直接使用 gitea 的账号登录,登录后进入 Token 页面就可以获取帐号的 token 将其设置到终端的环境变量中就可以使用命令管理 drone 了。
部署
安装完成后进入 drone 页面登录 gitea 的账号即可看到所有有权限的账号,打开开关后 drone 就会自动在 gitea 内注册 webhook
Golang 项目
- .dron.yml- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100- clone: 
 git:
 image: plugins/git
 # 没有 submodules 时可以关闭改选项
 recursive: false
 # 推荐使用较浅的深度,加快源码下载速度
 depth: 1
 # 条件分支 master
 branches: [ master ]
 pipeline:
 # 使用 cache 插件恢复缓存的 vendor 目录
 restore-cache:
 image: drillster/drone-volume-cache
 # 恢复缓存参数
 restore: true
 mount:
 - ./vendor
 volumes:
 # 这里使用了 volumes 属性,需要开启仓库受信任选项
 - /var/local/drone-cache:/cache
 build:
 # 这里使用了定制 golang 镜像,安装好了 make 以及 dep
 # 自定义镜像的 registry 需要单个项目配置
 # drone registry add -repository <repository> -hostname registry.yourdomain.com -username deployer -password <password>
 # docker pull 的命令实际上是通过 drone/agent 在宿主机上完成的
 # 所以应该预先使用 docker login 在宿主机上登录自建 registry 的账号
 image: registry.yourdomain.com/dep
 # 由于一些不可描述的原因导致很多 golang 包不能下载,一套 http 代理是必须的
 environment:
 - HTTP_PROXY=172.17.0.1:8118
 - HTTPS_PROXY=172.17.0.1:8118
 # dront build 的默认工作目录格式通常为 /dron/src/<org>/<repository>
 # 和 GOPATH 的路径一致,并且 dep 要求项目必须在 GOPATH 下,所以要将 /drone 设置为 GOPATH
 - GOPATH=/drone
 volumes:
 # 编译脚本中用到了时间参数所以需要同步宿主机的时区文件
 - /etc/localtime:/etc/localtime:ro
 commands:
 - dep ensure -v
 # 使用 Makefile 方便在开发过程中编译调试,后面提供文件内容
 - make
 deploy-test:
 # 使用 rsync 发布代码
 image: drillster/drone-rsync
 volumes:
 # 挂载 hosts 文件下面的 hosts 参数可以简写
 - /etc/hosts:/etc/hosts:ro
 hosts:
 - test01
 user: admin
 delete: true
 source: app
 target: /var/local/app
 script:
 ## 发布完成后重启容器
 - cd ~/docker/testing
 - docker-compose restart service1 service2
 when:
 # 当 master 分支收到新的推送时触发该步骤
 branch: master
 secrets:
 # 使用命令添加 ssh-key,用于 rsync 认证
 # 非企业用户只能分别为每个项目添加,不能使用全局密钥功能
 # drone secret add -repository <repository> -name rsync_key -value @/home/admin/.ssh/id_rsa
 - rsync_key
 deploy-prod:
 image: drillster/drone-rsync
 volumes:
 - /etc/hosts:/etc/hosts:ro
 hosts:
 - prod01
 user: admin
 delete: true
 source: app
 target: /var/local/app
 script:
 - cd ~/docker/production
 - docker-compose restart app1 app2
 when:
 # tag 事件需要开启仓库接受 tag 的事件选项,本来文档提示可以增加 branch 参数以限制 tag 是打在某个分支上的
 # 但是 gitea webhook 推送的分支名类似 refs/tags/20180607 不能匹配
 # 所以不能同时添加 branch 参数,可能 gitlab, github 是可以的
 event: tag
 secrets:
 - rsync_key
 rebuild-cache:
 # 使用 cache 插件缓存 vendor 目录
 image: drillster/drone-volume-cache
 # 构建缓存参数
 rebuild: true
 mount:
 - ./vendor
 volumes:
 - /var/local/drone-cache:/cache
- Makefile- 1 
 2
 3
 4
 5
 6
 7- APP=app 
 VERSION=`date +'%Y-%m-%d_%H:%M:%S'`
 FLAGS="-s -w -X main.Version=${VERSION}"
 build:
 go build -gcflags=-trimpath=${GOPATH} -asmflags=-trimpath=${GOPATH} -tags=jsoniter -o ${APP} -ldflags ${FLAGS}
 clean:
 @rm ${APP}
前端项目
- .drone.yml- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67- clone: 
 git:
 image: plugins/git
 recursive: false
 depth: 1
 branches: [ master ]
 pipeline:
 restore-cache:
 image: drillster/drone-volume-cache
 restore: true
 mount:
 # 缓存 node_modules 文件夹
 - ./node_modules
 volumes:
 - /var/local/drone-cache:/cache
 build:
 # 由于一些不可描述的原因 npm 的有些包以及二进制依赖很难下载
 # 所以定制一个装了 cnpm 的镜像是有必要的
 image: registry.yourdomain.com/cnpm
 volumes:
 - /etc/localtime:/etc/localtime:ro
 commands:
 - cnpm install
 - cnpm run build
 deploy-prod:
 image: drillster/drone-rsync
 volumes:
 - /etc/hosts:/etc/hosts:ro
 hosts:
 - prod01
 user: admin
 delete: true
 # source 目录的写法,不然会把编译后的文件发布到在目标目录的 dist 目录下
 source: ./dist/.
 target: /var/local/www/app/surfaces
 when:
 event: tag
 secrets:
 - rsync_key
 deploy-test:
 image: drillster/drone-rsync
 volumes:
 - /etc/hosts:/etc/hosts:ro
 hosts:
 - test01
 user: admin
 delete: true
 source: ./dist/.
 target: /var/local/www/app/surfaces
 when:
 branch: master
 secrets:
 - rsync_key
 rebuild-cache:
 image: drillster/drone-volume-cache
 rebuild: true
 mount:
 - ./node_modules
 volumes:
 - /var/local/drone-cache:/cache
其他
- 使用特殊的 commit message 跳过自动部署 - 可以通过添加 - [CI SKIP]到提交信息(commit message)中来让 Drone 跳过某个提交。注意,这里的文本是大小写不敏感的。
- 由于 jenkins workspace 的惯性思考,导致我一直以为有方法可以持久化保留构建过程中的 workspace,以便于挑过下次构建时在重新完整克隆,实际上官方文档有解释 workspace 每次是相当于执行 docker volume create 而创建的,http://docs.drone.io/workspace/ 而且不能二次挂载。不过重新克隆也有降级方案解决,如果仓库历史很冗长,可以通过设置克隆深度解决,如果仓库里的文件庞大可以考虑定制内置的 git 插件替换 克隆逻辑,有人已经有现成的插件输出,虽然他不建议这么做:https://github.com/drone-plugins/drone-git/tree/next 
- todo - 配置文件的发布 - 目前还没找到一个合适插件可以渲染服务配置文件 
- approve 机制 - drone 的命令里有提供 build 的 approve 和 reject 功能,不过暂时没在文档上找到怎么启用 
 
最后
Drone 是一个轻量级,为容器构建的强大的持续交付平台,依托 docker 强大的生态可以发挥出无限想象 :)