Gitea 與 Drone 整合實踐:完全基於 Docker 搭建的輕量級 CI/CD 系統

2022-09-21 18:00:29

Drone 是一個使用 Go 語言編寫的自助式的持續整合平臺,和 Gitea 一樣可以完全基於容器部署,輕鬆擴充套件流水線規模。開發者只需要將持續整合過程通過簡單的 YAML 語法寫入 Gitea 倉庫目錄下的描述檔案 .drone.yml 就可以完成 CI/CD 設定。

下面,我們以 gitea.com 伺服器為例,搭建一套使用 Gitea 與 Drone 的 CI/CD 系統。

系統結構

Drone 由兩部分構成:

  • Server
    負責任務排程
  • Runner
    執行 Pipeline 的具體任務

使用者將程式碼推播到 Gitea 時觸發 Webhook,調動 Drone 從 Gitea 拉取最新的程式碼並根據 .drone.yml 描述檔案執行 CI/CD 流水線。

網路結構

由於 CI/CD 任務的特殊性,工作繁忙時會佔用較多的系統資源,因此為了提高系統整體可靠性,不建議將 Gitea、Drone Server、Drone Runner 安裝在同一臺伺服器上。

  • 在本地區域網搭建時應該確保以上服務可以通過域名、IP互相存取。例如:
    gitea.example.com  ->  192.168.3.10
    drone.example.com  ->  192.168.3.20
    runner.example.com ->  192.168.3.30
    
  • 如需使用 docker compose 在本地開發環境搭建高可用結構系統,請參考官方檔案:
    https://docs.drone.io/server/ha/developer-setup/

準備工作

在 Gitea 上建立 OAuth2 應用程式

在本例中,Drone 基於 OAuth2 認證授權存取您的 Gitea API。您可以建立一個專用於 CI/CD 的賬號,並將該賬號新增為程式碼倉庫共同作業者或者組織管理員。

首先,登入一個您要用於整合 Drone 的 Gitea 賬號,進入 設定 - 應用,建立一個 Gitea OAuth2 應用程式。

  • 應用名稱
    您可以任取一個名字,此案例中我們填寫 Drone
  • 重定向 URL
    授權回撥 URL 形如 http(s)://<YOUR_DRONE_SERVER>:<PORT>/login,必須使用您設定的 Drone 伺服器協定和主機地址。如果使用非標準的HTTP(S)埠,還應該指定準確的埠。
    例如 https://drone.gitea.io/login

修改 Gitea 伺服器的 Webhook 白名單

出於安全考慮,Gitea 預設禁止觸發外部主機的 Webhook。您可以將外部主機新增到 webhook.ALLOWED_HOST_LIST 白名單來解除這一限制。具體資訊參考檔案 Webhook

修改設定時,開啟 conf/app.ini,新增 ALLOWED_HOST_LIST = *[webhook] 欄目中,並重啟 Gitea 伺服器。例如:

[webhook]
ALLOWED_HOST_LIST = *

建立共用金鑰

共用金鑰用於 Drone Server 和 Drone Runner 之間的通訊認證。記錄下您建立的共用金鑰,稍後在安裝 Drone Server 和 Drone Runner 時將使用此金鑰填充環境變數 DRONE_RPC_SECRET

您可以使用 OpenSSL 生成隨機的十六進位制共用金鑰:

$ openssl rand -hex 16
c5704bc389f1e3d47f1c4751d1295c86

使用 Docker 安裝 Drone 伺服器

Drone 伺服器是一個輕量級的 Docker 容器,使用 SQLite 作為預設資料庫,支援通過環境變數動態設定執行引數。有關設定引數的完整列表,請參閱 Drone Server 檔案

環境變數

  • DRONE_GITEA_CLIENT_ID
    (必填)您的 Gitea OAuth 使用者端ID
  • DRONE_GITEA_CLIENT_SECRET
    (必填)您的 Gitea OAuth 使用者端金鑰
  • DRONE_GITEA_SERVER
    (必填)您的 Gitea 伺服器地址,例如 https://gitea.com。注意填寫準確的 http(s) 協定,否則您會看到來自 Gitea 的錯誤報告:unsupported protocol scheme
  • DRONE_RPC_SECRET
    (必填)在準備工作中使用 openssl rand -hex 16 生成的共用金鑰。這個金鑰用於驗證 Drone Server 和 Runner 之間的 RPC 連線。因此,在 Server 和 Runner 上都必須使用相同的金鑰。
  • DRONE_SERVER_HOST
    (必填)您存取 Drone 時所用的域名或 IP 地址。如果使用 IP 地址,還應該包含埠。 例如 drone.gitea.io
  • DRONE_SERVER_PROTO
    (必填)設定伺服器的協定,使用:httphttps。 如果您已經設定 ssl 或 acme,此欄位預設為 https

啟動伺服器

為了便於修改容器引數,我們建立一個 docker-compose.yml 模板來設定 Drone 伺服器容器。

根據下面的 Docker Compose 模板,使用命令 docker compose up -d 啟動 Drone 伺服器。

# docker-compose.yml
version: "3"

services:
  drone:
    image: drone/drone:2
    container_name: drone
    environment:
      - DRONE_GITEA_SERVER=https://gitea.com
      - DRONE_GITEA_CLIENT_ID=change-to-your-gitea-client-id
      - DRONE_GITEA_CLIENT_SECRET=change-to-your-gitea-client-secret
      - DRONE_RPC_SECRET=change-to-your-shared-secret
      - DRONE_SERVER_HOST=drone.gitea.io
      - DRONE_SERVER_PROTO=https
    restart: always
    volumes:
      - ./drone:/data
    ports:
      - 80:80
      - 443:443

使用 Docker 安裝 Drone Runner

Drone 伺服器管理 CI/CD 系統的排程,而 Drone Runner 則是 CI/CD 流水線的執行者。

環境準備

Drone Runner 支援多種執行環境:Doceker、K8s、Windows/Linux/MacOS使用者端、SSH 等。

使用 Docker 作為 Drone Runner 的好處是可以將流水線執行過程完全以容器化的方式執行,不對容器的宿主伺服器環境造成破壞。在本實踐中,我們依然使用 Docker 在 Linux 伺服器上安裝 Drone Runner。Docker 容器支援的架構包括:

  • amd64
  • arm
  • arm64

環境變數

Docker Runner 使用環境變數動態設定執行引數。有關引數的完整列表,請參閱 Drone Runner 檔案

  • DRONE_RPC_HOST
    填寫 Drone Server 的主機名(以及可選填的埠號)。基於 PRC 協定連線 Runner 與 Server,接收流水線任務
  • DRONE_RPC_PROTO
    傳輸協定:httphttps
  • DRONE_RPC_SECRET
    與 Drone Server 共用的金鑰
  • DRONE_RUNNER_CAPACITY
    Runner 可以並行執行的流水線數量,預設:2
  • DRONE_RUNNER_NAME
    自定義 Runner 名稱

啟動 Runner

根據下面的 Docker Compose 模板,使用命令 docker compose up -d 啟動 Drone Runner。

version: "3"

services:
  runner:
    image: drone/drone-runner-docker:1
    container_name: runner
    environment:
      - DRONE_RPC_PROTO=https
      - DRONE_RPC_HOST=drone.gitea.io
      - DRONE_RPC_SECRET=change-to-your-shared-secret
      - DRONE_RUNNER_CAPACITY=2
      - DRONE_RUNNER_NAME=my-first-runner
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - 3000:3000

驗證安裝

使用 docker logs 命令檢視紀錄檔,並驗證 Runner 程式是否與 Drone Server 建立連線。

$ docker logs runner

INFO[0000] starting the server
INFO[0000] successfully pinged the remote server 

初始化 Drone

登入 Drone 網頁面板,例如 https://drone.gitea.io,點選 continue 跳轉到 Gitea 授權頁面,點選應用授權

如果出現 Unregistered Redirect URI,表示您設定的重定向 URI與 Drone 不匹配,請重新檢查。


CI/CD 實操:建立 .drone.yml 驗證 Pipeline

Drone 檔案為各種程式語言和包管理工具提供了流水線模板。

https://docs.drone.io/pipeline/docker/examples/

這裡我們以 Go 語言為例,在 Gitea 倉庫根目錄建立一個 .drone.yml 作為我們自定義的流水線。

示範:

# .drone.yml
kind: pipeline
name: default

steps:
- name: test
  image: golang
  commands:
  - go test

- name: build
  image: golang
  commands:
  - go build

在 Drone 面板上啟用倉庫後提交程式碼到 Gitea 倉庫,隨即觸發 Pipeline 任務。

回到 Gitea 可以看到構建完成後顯示的訊息:

✔ continuous-integration/drone/push Build is passing

Ok,這樣我們就為 Gitea 搭建好了一個 Drone CI/CD 系統。