<style>
.textleft {
text-align:left;
}
.reveal, .reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 {
font-family:Arial, Microsoft JhengHei;}
.reveal .progress {
height: 14px !important;
}
.progress span {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAMCAIAAAAs6UAAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUNCQzIyREQ0QjdEMTFFMzlEMDM4Qzc3MEY0NzdGMDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUNCQzIyREU0QjdEMTFFMzlEMDM4Qzc3MEY0NzdGMDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQ0JDMjJEQjRCN0QxMUUzOUQwMzhDNzcwRjQ3N0YwOCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQ0JDMjJEQzRCN0QxMUUzOUQwMzhDNzcwRjQ3N0YwOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PovDFgYAAAAmSURBVHjaYvjPwMAAxjMZmBhA9H8INv4P4TPM/A+m04zBNECAAQBCWQv9SUQpVgAAAABJRU5ErkJggg==) repeat-x !important;
}
.progress span:after, .progress span.nyancat {
content: "";
background: url(data:image/gif;base64,R0lGODlhIgAVAKIHAL3/9/+Zmf8zmf/MmZmZmf+Z/wAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpDMkJBNjY5RTU1NEJFMzExOUM4QUM2MDAwNDQzRERBQyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCREIzOEIzMzRCN0IxMUUzODhEQjgwOTYzMTgyNTE0QiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCREIzOEIzMjRCN0IxMUUzODhEQjgwOTYzMTgyNTE0QiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkM1QkE2NjlFNTU0QkUzMTE5QzhBQzYwMDA0NDNEREFDIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMyQkE2NjlFNTU0QkUzMTE5QzhBQzYwMDA0NDNEREFDIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8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) ;
width: 34px !important;
height: 21px !important;
border: none !important;
float: right;
margin-top: -7px;
margin-right: -10px;
}
.my-icon-css {
width: 100%;
height: 200px;
background-position:center;
background-repeat: no-repeat;
background-image:url('https://mir-s3-cdn-cf.behance.net/project_modules/disp/fe36cc42774743.57ee5f329fae6.gif');
}
</style>
<!-- .slide: data-transition="convex" -->
# <h2>Drone 第一次 CI/CD 就上手</h2>
@Kais(VagrantPi)
###### tags: `Drone`, `CI/CD`, `簡報`
---
<!-- .slide: data-transition="convex" -->
## agenda
----
<!-- .slide: data-transition="convex" -->
- 優缺點
- 架構 & 架設
- pipeline 教學
- command line
- 好用的 plugin
---
<!-- .slide: data-transition="convex" -->
## 優缺點
----
<!-- .slide: data-transition="convex" -->
### 優點
- <h2><b>很潮</b></h2>
- 學習成本低(會 docker 前提下)
- 可加入版控
- 套件每種語言都能寫
- 支援大部分平台(Github/Bitbucket/Gitlab/Gogs)
----
<!-- .slide: data-transition="convex" -->
### 缺點
- 還很年輕(文件缺東缺西)
- 套件還不夠多
- Web UI 過於簡陋(需要 command line 支援)
---
<!-- .slide: data-transition="slide" -->
## 架構 & 架設
----
<!-- .slide: data-transition="convex" -->
![](https://i.imgur.com/9qfjqAZ.png)
----
<!-- .slide: data-transition="convex" -->
### 架設(以 Bitbucket 為例)
Bitbucket 設定 > View profile > OAuth
> 詳細步驟可以直接參考上面第一篇連結,或是看我寫的 :smile:
> [Re: 從零開始的 CI 生活 - Drone](https://vagrantpi.github.io/2018/09/28/drone-101/)
----
<!-- .slide: data-transition="convex" -->
### docker-compose
```diff
version: '2'
services:
drone-server:
image: drone/drone:0.8
ports:
- 80:8000
- 9000
volumes:
- /var/lib/drone:/var/lib/drone/
restart: always
environment:
- DRONE_OPEN=true
# drone-server IP,如果要在 local 端測試,可以使用 ngrok
- DRONE_HOST=${DRONE_HOST}
# Set to true to enable the Bitbucket driver.
+ - DRONE_BITBUCKET=true
# Bitbucket oauth2 client id
+ - DRONE_BITBUCKET_CLIENT=${DRONE_BITBUCKET_CLIENT}
# Bitbucket oauth2 client secret
+ - DRONE_BITBUCKET_SECRET=${DRONE_BITBUCKET_SECRET}
# drone server 與 agent 溝通的 secret key
- DRONE_SECRET=${DRONE_SECRET}
drone-agent:
image: drone/agent:0.8
restart: always
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
# drone-server 位置
- DRONE_SERVER=drone-server:9000
# 跟上面的一樣
- DRONE_SECRET=${DRONE_SECRET}
```
http://docs.drone.io/install-for-bitbucket-cloud/
----
<!-- .slide: data-transition="convex" -->
### Drone 上的帳號管理
```diff
services:
drone-server:
image: drone/drone:0.8
environment:
+ - DRONE_OPEN= true
+ - DRONE_ORGS: kaislin,joe_hsu
```
----
<!-- .slide: data-transition="convex" -->
```diff
services:
drone-server:
image: drone/drone:0.8
environment:
- - DRONE_OPEN=true
+ - DRONE_OPEN=false
+ - DRONE_ADMIN=kaislin,joe_hsu
```
這樣只能透過 admin 去手動添加 user
```
drone user add <username>
```
---
<!-- .slide: data-transition="convex" -->
## pipeline 教學
----
<!-- .slide: data-transition="convex" -->
> 跟 docker-compose 有 87% 像
----
<!-- .slide: data-transition="convex" -->
### workspace(docker's volumes)
```
workspace:
base: /go/src
path: hello-drone
```
----
<!-- .slide: data-transition="convex" -->
### tags
```
clone:
git:
image: plugins/git
tags: true
```
----
<!-- .slide: data-transition="convex" -->
### Service
```dockerfile
services:
database:
image: mongo:4.0.2
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=admin
- MONGO_INITDB_DATABASE=MYDB
```
----
<!-- .slide: data-transition="convex" -->
### secrets
```
$ drone secret add \
--name MONGO_INITDB_ROOT_USERNAME \
--value admin \
--image mongo:4.0.2 \
--repository kaislin/hello-drone
```
or
![](https://i.imgur.com/IVsGEO4.png)
----
<!-- .slide: data-transition="convex" -->
```diff
services:
database:
image: mongo:4.0.2
+ secrets: [ MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD]
environment:
- - MONGO_INITDB_ROOT_USERNAME=admin
- - MONGO_INITDB_ROOT_PASSWORD=admin
- MONGO_INITDB_DATABASE=MYDB
```
----
<!-- .slide: data-transition="convex" -->
### 自訂 pipeline step
```dockerfile
test:
image: golang:1.9.4
volumes:
- /home/ubuntu/hello-drone-config:/etc/mrt
commands:
- cp -rf config/hello-drone/router /hello-drone/mrt/
- cp -rf config/hello-drone/smtp /hello-drone/mrt/
- go test ./...
- go test -cover
```
----
<!-- .slide: data-transition="convex" -->
### 並行執行(Parallel Execution)
```diff
pipeline:
backend:
+ group: build
image: golang
commands:
- go build
- go test
frontend:
+ group: build
image: node
commands:
- npm install
- npm run test
- npm run build
publish:
image: plugins/docker
repo: octocat/hello-world
```
----
<!-- .slide: data-transition="convex" -->
### skip branch
```diff
pipeline:
build:
image: golang
commands:
- go build
- go test
-branches: master
-branches: [ master, develop ]
+branches: [ master, feature/* ]
```
----
<!-- .slide: data-transition="convex" -->
### 只關注的 branch
```diff
pipeline:
build:
image: golang
commands:
- go build
- go test
+branches:
+ include: [ master, feature/* ]
```
----
<!-- .slide: data-transition="convex" -->
### 排除 branch
```diff
pipeline:
build:
image: golang
commands:
- go build
- go test
+branches:
+ exclude: [ develop, feature/* ]
```
----
<!-- .slide: data-transition="convex" -->
### 當有 tag 時
```
when:
event: tag
```
![](https://i.imgur.com/4XEdWxe.png)
----
<!-- .slide: data-transition="convex" -->
### Volumes
用法跟 docker-compose 差不多
```diff
pipeline:
build:
image: docker
commands:
- docker build --rm -t octocat/hello-world .
- docker run --rm octocat/hello-world --test
- docker push octocat/hello-world
- docker rmi octocat/hello-world
volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
```
![](https://i.imgur.com/Xiyv4jZ.png)
----
<!-- .slide: data-transition="convex" -->
### Environment
```diff
pipeline:
build:
image: golang
+ environment:
+ - CGO=0
+ - GOOS=linux
+ - GOARCH=amd64
commands:
- go build
- go test
```
----
<!-- .slide: data-transition="convex" -->
### deploy
```diff
pipeline:
build:
image: golang
commands:
- go build
- go test
publish:
image: plugins/docker
registry: registry.heroku.com
repo: registry.heroku.com/my-staging-app/web
when:
+ event: deployment
+ environment: staging
publish_to_prod:
image: plugins/docker
registry: registry.heroku.com
repo: registry.heroku.com/my-production-app/web
when:
+ event: deployment
+ environment: production
```
----
<!-- .slide: data-transition="convex" -->
### deploy command
部署使用 command line
```
drone deploy <repo> <build> <environment>
```
指定部署 24 到 staging 環境
```
drone deploy octocat/hello-world 24 staging
```
指定部署 24 到 production 環境
```
drone deploy octocat/hello-world 24 production
```
---
<!-- .slide: data-transition="convex" -->
## command line
----
<!-- .slide: data-transition="convex" -->
### token
使用前須先從 web UI 拿到 token 才能夠透過 command 戳 drone
----
<!-- .slide: data-transition="convex" -->
### build
drone build start kaislin/hello-drone 36
drone build stop kaislin/hello-drone 36
---
<!-- .slide: data-transition="convex" -->
## 好用的 plugin
----
<!-- .slide: data-transition="convex" -->
### ssh
```dockerfile
deploy-production:
image: appleboy/drone-ssh
pull: true
host: <host ip>
username: <username>
secrets: [ ssh_password ]
script:
- docker pull XXX.XXX.XXX.XXX:5000/hello-drone
- docker tag XXX.XXX.XXX.XXX:5000/hello-drone hello-drone:latest
- cd /home/ubuntu/hello-drone/docker
- docker-compose down
- docker-compose up -d
when:
branch: develop
event: deployment
```
----
<!-- .slide: data-transition="convex" -->
### slack
```dockerfile
slack:
image: plugins/slack
channel: drone_test
webhook: https://hooks.slack.com/services/.....
when:
status: [ success, failure ]
```
----
<!-- .slide: data-transition="convex" -->
### cache
如 node_module 或 vendor 之類的資料希望能夠 cache
```dockerfile
restore-cache:
image: drillster/drone-volume-cache
restore: true
mount:
- ./vendor
volumes:
- /tmp/cache:/cache
dependency:
image: marcelocorreia/go-glide-builder
commands:
- sh docker/glide_install.sh
rebuild-cache:
image: drillster/drone-volume-cache
rebuild: true
mount:
- ./vendor
volumes:
- /tmp/cache:/cache
```
{"metaMigratedAt":"2023-06-14T18:19:34.315Z","metaMigratedFrom":"Content","title":"<h2>Drone 第一次 CI/CD 就上手</h2>","breaks":true,"contributors":"[{\"id\":\"69ade472-3ed3-499d-8a69-767243a31621\",\"add\":18439,\"del\":3514}]"}