Skip to content

介绍

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

缺点

  1. 没有中文文档
  2. 功能比较轻量级(但是搭配 gitea/gitness 足够应付多数情况的开发任务了)
  3. 插件较少, 也不兼容 github actions

虽然实现了 "跨git管理软件" 且完全开源, 但是缺点也很明显, 社区不够强大, 插件较少

笔记对应的代码

plugins

和 github actions 类似, 它也有类似的插件市场

安装 gitea + Drone CI

创建 docker-compose.yml

yaml
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
sh
# 启动
docker compose up -d

注册 gitea oauth app

点击头像 -> 设置 -> 应用

注意地址不要填错, 要填写真实的地址, 获取 client_idclient_secret

修改 docker-compose.yml

  1. 修改 oauth 登录信息
  • DRONE_GITEA_CLIENT_ID: your_client_id
  • DRONE_GITEA_CLIENT_SECRET: your_client_secret
  1. 修改 runner 和 drone-server 的通信密钥
  • DRONE_RPC_SECRET: your_rpc_secret
sh
# 生成一个随机通信密钥
openssl rand -hex 16
  1. 修改完之后重新启动
sh
docker compose down
docker compose up -d
  1. 查看 drone-server 和 runner 是否链接成功
sh
# drone-runner 是在 docker-compose.yml 中定义的容器名
docker compose logs -f drone-runner

# 如果出现如下图中显示的内容就证明链接成功了

如果环境没有问题, 登录 gite 创建项目, 然后提交代码, 然后登录 drone

部署项目到自己的服务器

准备步骤

  1. 还是使用 vitepress 项目
  2. 还是需要一台公网能够访问的服务器(两台更好: 一台部署 gitea + drone, 一台部署项目)

创建 secrets

  1. 登录 drone-server
  2. sync 同步代码库: 先 Active 激活, 然后勾选 Trusted (如果不是管理员用户登录,无法看到这个选项)
  3. 创建 secrets

就是一些变量, 类似 gitub 的那个 Repository secrets

创建流水线配置文件

在项目根目录下创建: .drone.yml 内容如下

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 ====="

创建部署脚本

sh
#!/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 分支即可触发

Released under the MIT License.