介绍
Drone CI 是一个开源的持续集成和持续部署工具,它使用 Docker 容器来运行构建和测试任务,并支持多种代码仓库
注: 如果你是第一次学 CICD, 我是不推荐这个的, 还是更推荐 jenkins / gitlab 等 比较知名的开源项目, 因为这些项目名气更大, 周边生态更丰富
为什么用 Drone CICD ?
为什么不使用更知名的 travis 或者 jenkins ?
呃...这个可能是因为第一印象 😄😄😄 由于我最开始接触 cicd 就是用的是这个, 为了后面方便查阅, 做个笔记
免费的 runner 配置低
不管是 Github Actions 还是 GitLab CICD 都是没有办法直接运行流水线(或者叫工作流)定义的那些任务的, 都需要 Runner
, 那么这样就会导致一个问题, 如果是使用 gitlab.com 或者 github.com 提供的免费 runner, 他们的配置并不高, 如果大项目编译/测试/打包就会非常慢, 如果需要更高的配置, 还是需要自己去配置注册 runner
gitlab 和 github 流水线配置文件无法通用
使用 Github Actions 就要去学一次 Github Actions 配置文件的字段语法等, 用 GitLab CICD 又需要再学一次, 这就很难受了...
有没有什么办法可以: 只学一次然后在各个平台(gitlab/github/gitea/gogs/bitbucket)都能使用的 流水线配置文件和 runner
缺点
- 没有中文文档
- 功能比较轻量级(但是搭配 gitea/gitness 足够应付多数情况的开发任务了)
- 插件较少, 也不兼容 github actions
虽然实现了 "跨git管理软件" 且完全开源, 但是缺点也很明显, 社区不够强大, 插件较少
笔记对应的代码
plugins
和 github actions 类似, 它也有类似的插件市场
安装 gitea + Drone CI
创建 docker-compose.yml
version: "3"
networks:
gitea:
external: false
services:
gitea_server:
image: gitea/gitea:1.21.2
container_name: gitea
hostname: giteaserver
environment:
USER_UID: 1000
USER_GID: 1000
GITEA__database__DB_TYPE: postgres
GITEA__database__HOST: 'db:5432'
GITEA__database__NAME: gitea # 注意要和 db 的 environment 中填的一样
GITEA__database__USER: admin
GITEA__database__PASSWD: admin1314
restart: always
depends_on:
- db
networks:
- gitea
volumes:
- ./gitea_data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "8000:3000"
- "8001:22"
db:
image: postgres:14
container_name: postgres
restart: always
hostname: postgres_server
environment:
POSTGRES_DB: gitea # 数据库名
POSTGRES_USER: admin # 数据库用户
POSTGRES_PASSWORD: admin1314 # 数据库密码
networks:
- gitea
ports:
- "8002:5432"
volumes:
- ./postgres_conf:/etc/postgresql
- ./postgres_data:/var/lib/postgresql/data
# for cicd
drone:
image: drone/drone:2
container_name: drone
restart: always
hostname: droneserver
depends_on:
- db
networks:
- gitea
ports:
- '8003:80'
volumes:
- ./drone_config:/var/lib/drone
environment:
TZ: Asia/Shanghai
DRONE_GITEA_SERVER: https://gitea.examples.cn # gitea 部署的域名
DRONE_GITEA_CLIENT_ID: c4d3610e-f3bb-4224-857f-fb27c7712345 # gitea client id
DRONE_GITEA_CLIENT_SECRET: gto_spqtexjlzwgyqx77pyq57hmye2r5qakeq6uug6uqliocxjm12345 # gitea client secret
DRONE_RPC_SECRET: cbce82a5d5e5772b8daf59202c612345 # 与 runner 通信的 secret
DRONE_SERVER_HOST: https://dronecicd.examples.cn # drone 部署的域名
DRONE_SERVER_PROTO: https # 注意协议
DRONE_USER_CREATE: username:secret,admin:true # 超级管理员账号
DRONE_DATABASE_DRIVER: postgres # 使用这个文件定义的服务, 而不是镜像内部的 pgsql
DRONE_DATABASE_DATASOURCE: postgres://admin:admin1314@postgres_server:5432/postgres?sslmode=disable
# cicd runner
drone-runner:
image: drone/drone-runner-docker:1
restart: always
container_name: drone-runner
depends_on:
- drone
networks:
- gitea
ports:
- '8004:3000'
environment:
DRONE_RPC_HOST: droneserver # 注意需要在同一 network 下才可以使用 hostname
DRONE_RPC_PROTO: http # 注意协议是 http, 因为现在走的是 hostname 所以不是 https
DRONE_RPC_SECRET: cbce82a5d5e5772b8daf59202c612345 # runner 与 drone server 通信的 secret
DRONE_UI_USERNAME: root
DRONE_UI_PASSWORD: root
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# 启动
docker compose up -d
注册 gitea oauth app
点击头像 -> 设置 -> 应用
注意地址不要填错, 要填写真实的地址, 获取 client_id
和 client_secret
修改 docker-compose.yml
- 修改 oauth 登录信息
- DRONE_GITEA_CLIENT_ID: your_client_id
- DRONE_GITEA_CLIENT_SECRET: your_client_secret
- 修改 runner 和 drone-server 的通信密钥
- DRONE_RPC_SECRET: your_rpc_secret
# 生成一个随机通信密钥
openssl rand -hex 16
- 修改完之后重新启动
docker compose down
docker compose up -d
- 查看 drone-server 和 runner 是否链接成功
# drone-runner 是在 docker-compose.yml 中定义的容器名
docker compose logs -f drone-runner
# 如果出现如下图中显示的内容就证明链接成功了
如果环境没有问题, 登录 gite 创建项目, 然后提交代码, 然后登录 drone
部署项目到自己的服务器
准备步骤
- 还是使用 vitepress 项目
- 还是需要一台公网能够访问的服务器(两台更好: 一台部署 gitea + drone, 一台部署项目)
创建 secrets
- 登录 drone-server
- sync 同步代码库: 先
Active
激活, 然后勾选Trusted
(如果不是管理员用户登录,无法看到这个选项) - 创建 secrets
就是一些变量, 类似 gitub 的那个 Repository secrets
创建流水线配置文件
在项目根目录下创建: .drone.yml
内容如下
---
kind: pipeline
type: docker
name: deploy
# push 代码的时候就触发这个流水线
trigger:
event:
- push
# 定义缓存目录(放到宿主机的 /tmp/drone_cache 目录下)
volumes:
- name: cache
host:
path: /tmp/drone_cache
steps:
# 使用缓存(如果有的话)
- name: restore-cache
image: drillster/drone-volume-cache
pull: if-not-exists
volumes:
- name: cache
path: /cache
settings:
restore: true
mount:
- ./node_modules
# 安装依赖 编译源码 压缩打包
- name: build-and-compress-source-code
image: node:18
pull: if-not-exists
commands:
- npm install -g pnpm
- pnpm install --no-frozen-lockfile
- pnpm docs:build
- ls -al
- tar -cjvf dist.bz2 ./run.sh ./docs/.vitepress/dist
- echo "===== build completed ====="
# 制作缓存(需要指定缓存目录, 不要每次去下载 node_modules)
- name: rebuild-cache
image: drillster/drone-volume-cache
pull: if-not-exists
volumes:
- name: cache
path: /cache
settings:
rebuild: true
restore: false
mount:
- ./node_modules
# 将文件上传到服务器
- name: upload-file-to-server
image: appleboy/drone-scp
pull: if-not-exists
when:
branch: main # 只有在 push 到 main 分支才执行
settings:
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_user
password:
from_secret: ssh_pass
port:
from_secret: ssh_port
command_timeout: 2m
source: ./dist.bz2
target: ~/learn-drone-cicd-demo
# 连接上服务器然后执行一些脚本
- name: deploy-to-server
image: appleboy/drone-ssh
pull: if-not-exists
when:
branch: main # 只有在push 到 main 分支的时候才执行
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_user
password:
from_secret: ssh_pass
port:
from_secret: ssh_port
command_timeout: 2m
script:
- cd ~/learn-drone-cicd-demo
- tar -xjvf ./dist.bz2
- pwd
- ls -al
- chmod +x ./run.sh && ./run.sh
- echo "===== deploy completed ====="
创建部署脚本
#!/bin/bash
docker_container_name="learn-drone-cicd-demo"
docker_image_name="nginx:stable"
# 先停止原来的
docker stop $docker_container_name
docker rm $docker_container_name
# 启动容器
docker run -d \
-p 4000:80 \
-v $(pwd)/docs/.vitepress/dist:/usr/share/nginx/html \
--name $docker_container_name $docker_image_name
运行 & 查看
提交代码到 main 分支即可触发