gitea 安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| version: "2" services: web: image: gitea/gitea volumes: - ./data:/data ports: - "3000:3000" restart: always db: image: mariadb:10 restart: always environment: - MYSQL_ROOT_PASSWORD=xxxx - MYSQL_DATABASE=gitea - MYSQL_USER=gitea - MYSQL_PASSWORD=xxxxx volumes: - ./db/:/var/lib/mysql
|
drone 安装(server + runner)(请参考官方教程)
官方教程:
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
| version: "3"
services: server: image: drone/drone:1 container_name: drone_server restart: always environment: DRONE_GITEA_SERVER: https://git.xxxx.cn DRONE_GITEA_CLIENT_ID: "xxxxx" DRONE_GITEA_CLIENT_SECRET: "xxxxx" DRONE_RPC_SECRET: "xxxxx" DRONE_SERVER_HOST: ci.xxxxx.cn DRONE_SERVER_PROTO: https DRONE_USER_CREATE: username:xxxx,admin:true ports: - "3001:80" volumes: - "./data:/var/lib/drone"
runner: image: drone/drone-runner-docker container_name: drone_runner_docker restart: always environment: DRONE_RPC_PROTO: https DRONE_RPC_HOST: ci.xxxx.cn DRONE_RPC_SECRET: xxxxx DRONE_RUNNER_CAPACITY: 5 DRONE_UI_USERNAME: happyxhw DRONE_UI_PASSWORD: xxxxx DRONE_RUNNER_NAME: xxxxx DRONE_RUNNER_LABELS: role:xxxxx ports: - "8484:3000" volumes: - "/var/run/docker.sock:/var/run/docker.sock"
|
流水线配置(参考示例项目 .drone.yml)
push, pull_request,merge:
- linter: 执行 golangci-lint
- test
- build
- notification
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
| kind: pipeline name: drone-golang-example-dev-build
# 指定编译平台 platform: os: linux arch: amd64
# 指定代码空间,git代码会被clone到指定的path workspace: path: /drone/src
# type: docker, k8s, ssh, exec type: docker # 流水线 steps: - name: linter image: golang:latest # 编译用的镜像,最好在runner主机上提前下载好,否则会很慢,墙,一生之敌 pull: if-not-exists # 默认always,指定if-not-exists或never可以大幅度提高速度,pull在中国很费时 environment: GOPROXY: "https://goproxy.cn,direct" # 懂的都懂 volumes: # 缓存 go mod & pkg,可以大幅度提高速度,避免每次都下载 - name: pkgdeps path: /go/pkg commands: - go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.27.0 # golang下好评最高的linter工具,强迫症最爱 - golangci-lint run
- name: test image: golang:latest pull: if-not-exists environment: GOPROXY: "https://goproxy.cn,direct" volumes: - name: pkgdeps path: /go/pkg commands: - go test -v ./...
- name: build image: golang:latest pull: if-not-exists environment: GOPROXY: "https://goproxy.cn,direct" volumes: - name: pkgdeps path: /go/pkg commands: - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build # 使用alpine务必要指定 GO_ENABLED=0
- name: notification # 钉钉通知,自行探索 image: lddsb/drone-dingtalk-message pull: if-not-exists settings: token: from_secret: dingtalk_token # 敏感数据请使用 from_secret type: markdown secret: from_secret: dingtalk_secret sha_link: true message_color: true when: # 即使流水线失败也能通知 status: - success - failure
trigger: # 触发条件,并关系 branch: # git 分支 - develop - master event: # 事件 - push - pull_request
volumes: # 挂载,持久化数据 - name: pkgdeps host: path: /tmp/pkg
node: role: xxxx # 指定标签为role:xxxx的runner执行流水线
|
Drone | Continuous Integration
![](基于 gitea + drone + docker 的 CI 流程实践/v2-f9e22bde7e07201d1568f2d952648a7f_b.jpg)
- linter: 执行 golangci-lint
- test
- build
- publish: 发布镜像
- scp: 复制部署文件到目标部署主机
- deploy: 拉取镜像,重启容器
- notification
注意:
我在docker-compose.yml中将镜像的tag设置为了环境变量${DOCKER_TAG},在开发环境中我喜欢将DRONE_COMMIT作为镜像的tag;在生产环境中我喜欢将DRONE_TAG(tag 事件触发生产环境部署)作为镜像tag,这样的好处是可以快速回滚到指定版本。
此外也可以将部署流程自动化到git事件中(master merge后自动部署生产环境,不需要手动promote)
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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| # 编译、部署开发镜像, 主动触发 kind: pipeline name: drone-golang-example-dev-deploy
platform: os: linux arch: amd64
workspace: path: /drone/src
type: docker steps: - name: linter image: golang:latest pull: if-not-exists environment: GOPROXY: "https://goproxy.cn,direct" volumes: - name: pkgdeps path: /go/pkg commands: - go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.27.0 - golangci-lint run
- name: test image: golang:latest pull: if-not-exists environment: GOPROXY: "https://goproxy.cn,direct" volumes: - name: pkgdeps path: /go/pkg commands: - go test -v ./...
- name: build image: golang:latest pull: if-not-exists environment: GOPROXY: "https://goproxy.cn,direct" volumes: - name: pkgdeps path: /go/pkg commands: - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
- name: publish image: docker/compose pull: if-not-exists environment: USERNAME: from_secret: aliyun_registry_username PASSWORD: from_secret: aliyun_registry_password volumes: - name: dockersock path: /var/run/docker.sock commands: - tag=${DRONE_COMMIT} # 使用 DRONE_COMMIT 作为tag - echo "publish" - echo dev_$tag - export DOCKER_TAG=dev_$tag - docker login --username=$USERNAME registry.cn-hangzhou.aliyuncs.com -p $PASSWORD - docker-compose build - docker-compose push - - name: scp image: appleboy/drone-scp pull: if-not-exists settings: host: from_secret: dev_host username: from_secret: dev_user password: from_secret: dev_password port: 22 target: /home/xuhewen/drone-golang-example source: - docker-compose.yml
- name: deploy image: appleboy/drone-ssh pull: if-not-exists settings: host: from_secret: dev_host username: from_secret: dev_user password: from_secret: dev_password port: 22 script: - tag=${DRONE_COMMIT} # 请预先在目标主机上执行 docker login - echo "deploy" - echo dev_$tag - cd /home/xuhewen/drone-golang-example - export DOCKER_TAG=dev_$tag - docker-compose pull - docker-compose stop - docker-compose up -d
- name: notification image: lddsb/drone-dingtalk-message pull: if-not-exists settings: token: from_secret: dingtalk_token type: markdown secret: from_secret: dingtalk_secret sha_link: true message_color: true when: # 即使流水线失败也能通知 status: - success - failure
volumes: - name: pkgdeps host: path: /tmp/pkg - name: dockersock host: path: /var/run/docker.sock
trigger: event: - promote target: - develop # 指定部署环境: dev,stage,production
when: branch: - develop
node: role: xxxx
|
触发 promote:
![](基于 gitea + drone + docker 的 CI 流程实践/v2-c4a5ef1e6b0955dde4d9908d71ccd776_b.jpg)
Drone | Continuous Integration
![](基于 gitea + drone + docker 的 CI 流程实践/v2-296c70343b96b87b68340739ce602616_b.jpg)
成功部署:
![](基于 gitea + drone + docker 的 CI 流程实践/v2-88b6e0e8a778d8781224d27c5f66143a_b.jpg)
rollback:根据 DRONE_COMMIT 或 DRONE_TAG 快速回滚
- scp: 复制部署文件(clone时git已经切换到了需要回滚的版本)
- rollback: 根据 DRONE_COMMIT 或 DRONE_TAG 拉取指定tag的镜像进行回滚
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
| # 根据commit id回滚 kind: pipeline name: drone-golang-example-dev-rollback
platform: os: linux arch: amd64
workspace: path: /drone/src
type: docker steps: - name: scp image: appleboy/drone-scp pull: if-not-exists settings: host: from_secret: dev_host username: from_secret: dev_user password: from_secret: dev_password port: 22 target: /home/xuhewen/drone-golang-example source: - docker-compose.yml
- name: rollback image: appleboy/drone-ssh pull: if-not-exists settings: host: from_secret: dev_host username: from_secret: dev_user password: from_secret: dev_password port: 22 script: - tag=${DRONE_COMMIT} - echo "deploy" - echo dev_$tag - cd /home/xuhewen/drone-golang-example - export DOCKER_TAG=dev_$tag - docker-compose pull - docker-compose stop - docker-compose up -d
- name: notification image: lddsb/drone-dingtalk-message pull: if-not-exists settings: token: from_secret: dingtalk_token type: markdown secret: from_secret: dingtalk_secret sha_link: true message_color: true when: status: - success - failure
volumes: - name: dockersock host: path: /var/run/docker.sock
trigger: event: - rollback target: - develop # 指定部署环境: dev,stage,production
when: branch: - develop
node: role: xxxx
|
Drone | Continuous Integration
![](基于 gitea + drone + docker 的 CI 流程实践/v2-e7601b0c866cc762b64390f54a1751fb_b.jpg)
成功回滚到指定版本(’hello, to happyxhw’ 回滚到 ‘hi, from happyxhw’):
![](基于 gitea + drone + docker 的 CI 流程实践/v2-b8f3556bccb50089bb41de74bef436a0_b.jpg)
secrets:
![](基于 gitea + drone + docker 的 CI 流程实践/v2-6e17660da65691d41816a75557bd7e64_b.jpg)
镜像:
![](基于 gitea + drone + docker 的 CI 流程实践/v2-50cdbdf6a180f54a2d2b79dca451e781_b.jpg)
补充:
上面我只写出了开发环境中的CI流程,大家可以自行补充,比如加入预发布、生产环境的编译、部署和回滚流程,加入 master 分支、tag 事件的触发流程,具体请参考 drone 官方文档。