使用 GitHub Actions 自動化 Docker 映像構建與發佈流程

使用 GitHub Actions 自動化 Docker 映像構建與發佈流程
作者: Calpa Liu
字數:2659
出版:2025年3月20日

在當今的開發環境中,自動化發佈流程已成為提高開發效率的關鍵因素。本文將探討如何利用 GitHub Actions 構建 Docker 映像並推送到 DockerHub,以創建更高效、更可靠的發佈工作流程。

為何使用 GitHub Actions 進行 Docker 映像發佈?

CICD
CICD

在現代軟體開發中,持續集成和自動化已成為標準實踐。GitHub Actions 為 CI/CD 流程提供了強大的自動化功能,使開發人員能夠直接在代碼儲存庫中定義和執行工作流程。將 Docker 映像構建與發佈整合到 GitHub Actions 中有以下顯著優勢:

  1. 無縫整合:與 GitHub 代碼倉庫緊密結合,無需配置額外的 CI/CD 工具
  2. 自動化觸發:基於事件(如標籤推送、合併請求或定期排程)自動執行工作流程
  3. 版本控制:映像標籤與 Git 標籤保持一致,確保版本追蹤和可復現性
  4. 多平台支持:輕鬆實現跨平台映像構建,提高應用程序的兼容性
  5. 安全憑證管理:使用 GitHub Secrets 安全存儲敏感資訊,避免憑證外洩
  6. 負載均衡:利用 GitHub 的分散式執行環境,提高構建效率

Urusai 專案簡介

Urusai(うるさい,日語中”吵鬧”的意思)是一個使用 Go 語言實現的網絡流量噪聲生成器。它能在後台生成隨機的 HTTP/DNS 流量,使您的網絡流量數據變得不易被追蹤和利用,為您的網絡瀏覽提供額外的隱私保護。

Urusai 的 Docker 工作流程分析

讓我們深入分析 Urusai 專案中定義的 .github/workflows/docker.yml 文件。這個工作流程文件定義了如何自動化構建和發佈 Docker 映像的整個過程:

觸發條件

on:
  push:
    tags:
      - "v*"

該工作流程僅在推送符合 ‘v*’ 模式的標籤(如 v1.0.0)時觸發,這是一種常見的語義化版本標記方式。這確保了 Docker 映像只在正式發佈新版本時才被構建和推送。

這種基於標籤的觸發方式有幾個好處:

  • 清晰地區分了開發和發布環境
  • 確保只有正式版本才會被發布到 DockerHub
  • 與語義化版本控制(SemVer)完美配合

工作環境設定

jobs:
  docker:
    runs-on: ubuntu-latest

工作流程在最新的 Ubuntu 環境中執行,GitHub Actions 提供了完全託管的虛擬機器。選擇 ubuntu-latest 可確保我們的構建環境始終使用最新的安全更新和工具版本,這對於映像的安全性非常重要。

工作流程步驟詳解

1. 檢出代碼

- name: Checkout
  uses: actions/checkout@v4

使用官方的 checkout 動作將倉庫代碼克隆到運行環境中。值得注意的是,此動作對於使用「Path context」而非「Git context」構建 Docker 映像是必需的。

2. Docker Meta 配置

- name: Docker meta
  id: meta
  uses: docker/metadata-action@v5
  with:
    images: calpa/urusai
    tags: |
      type=semver,pattern={{version}}
      type=semver,pattern={{major}}.{{minor}}
      latest

metadata-action 負責為 Docker 映像提取標籤和標籤元數據。這個強大的動作自動化了標籤管理,使開發者無需手動設置每個版本的標籤。此配置會產生以下標籤:

  • 完整版本號(如 v1.2.3):允許用戶選擇特定版本
  • 主次版本號(如 1.2):方便用戶使用最新的修訂版本
  • latest 標籤:始終指向最新的穩定版本

這種多層次的標籤策略為用戶提供了靈活的選擇,方便在不同場景下選擇適合的映像版本:

  • 生產環境可以選擇特定版本以確保穩定性
  • 開發環境可以使用 latest 以保持更新

3. 設置 QEMU 以支持多平台

- name: Set up QEMU
  uses: docker/setup-qemu-action@v3

此步驟安裝 QEMU 靜態二進制文件,為多架構構建提供支持。

4. 設置 Docker Buildx

- name: Set up Docker Buildx
  uses: docker/setup-buildx-action@v3

Buildx 是 Docker 的構建擴展,它提供了更強大的構建功能,包括跨平台構建支持。

5. 登錄 Docker Hub

- name: Login to Docker Hub
  uses: docker/login-action@v3
  with:
    username: ${{ secrets.DOCKERHUB_USERNAME }}
    password: ${{ secrets.DOCKERHUB_TOKEN }}

使用儲存在 GitHub Secrets 中的憑證登錄到 Docker Hub。這種方式安全地管理敏感認證信息,避免在工作流程文件中硬編碼。

6. 構建和推送 Docker 映像

- name: Build and push
  uses: docker/build-push-action@v5
  with:
    context: .
    platforms: linux/amd64,linux/arm64,linux/arm/v7
    push: true
    tags: ${{ steps.meta.outputs.tags }}
    labels: ${{ steps.meta.outputs.labels }}

此步驟使用 build-push-action 構建 Docker 映像並將其推送到 Docker Hub。重要配置包括:

  • context: .:定義構建上下文為當前目錄
  • platforms:同時為多個平台(amd64、arm64、arm/v7)構建映像
  • push: true:成功構建後推送映像
  • tagslabels:使用前面的 metadata 步驟生成的標籤

7. DockerHub 上的映像

當工作流程成功完成後,映像將被推送到 DockerHub 上。如上圖所示,我們可以看到 Urusai 專案在 DockerHub 上的頁面。頁面提供了專案的基本信息,包括專案描述、功能特點和使用說明。右側還提供了一鍵拉取映像的命令 docker pull calpa/urusai,方便用戶快速開始使用。

8. 運行 Urusai

當我們成功構建並推送映像後,Docker Hub 上會顯示我們的映像,我們可以使用 calpa/urusai 來引用這個映像。從上圖可以看出,我們可以在 Docker Desktop 中成功運行 Urusai,並生成隨機的 HTTP/DNS 流量。

多平台支持的優勢

多平台 Docker 構建示意圖
多平台 Docker 構建示意圖

多平台構建是現代 Docker 工作流程的一個關鍵特性。在不斷多樣化的計算環境中,應用程序需要在不同的硬件架構上運行。通過 GitHub Actions 的多平台構建功能,我們可以在單一工作流程中為不同的硬件架構(amd64、arm64、arm/v7)構建映像。

這種方法為開發者和用戶帶來了顯著的好處:

  1. 廣泛兼容性:用戶可在任何硬件上使用相同的映像名稱,Docker 會自動選擇適合的架構
  2. 簡化開發與維護:維護一個工作流程和一個 Dockerfile,而非為每個平台分別維護
  3. 擴大用戶群:支持各種設備,從雲端服務器(amd64)到樹莓派(arm)和 IoT 設備
  4. 效能優化:每個架構的映像都將為該平台進行原生編譯,提供最佳性能
  5. 減少開發環境差異:開發者可以在任何平台上開發,並確保在所有平台上的一致性

設置您自己的 Docker 發佈工作流程

若要為您的專案設置類似的工作流程,您需要:

  1. 創建 DockerHub 訪問令牌

    • DockerHub 設置中生成訪問令牌
    • 將用戶名和令牌存儲在 GitHub Secrets 中作為 DOCKERHUB_USERNAMEDOCKERHUB_TOKEN
  2. 創建 Dockerfile

    • 在專案根目錄創建適合您應用的 Dockerfile
  3. 設置工作流程文件

    • .github/workflows/ 目錄中創建 YAML 文件
    • 參照上面的分析定制您的工作流程
  4. 發布版本

    • 創建並推送標籤以觸發工作流程:
      git tag v1.0.0
      git push origin v1.0.0

安全性考慮

在實現 Docker 發佈工作流程時,安全性是一個重要考量:

  1. 敏感資訊:使用 GitHub Secrets 存儲所有憑證和敏感資訊
  2. 最小權限:Docker Hub 訪問令牌應僅具有必要的權限
  3. 依賴掃描:考慮添加 Trivy 等工具對映像進行漏洞掃描
  4. 構建完整性:考慮生成和驗證構建證明以確保供應鏈安全

最佳實踐與改進

在使用 GitHub Actions 進行 Docker 映像發佈時,還可以考慮以下最佳實踐:

  1. 測試後推送:在推送映像前添加測試步驟
  2. 語義化版本:使用標準的語義化版本控制(SemVer)策略
  3. 腳本復用:建立可重用的工作流程模板
  4. 構建快取:利用 BuildKit 的快取機制加速構建過程

常見問題與故障排除

在實施 GitHub Actions Docker 工作流程時,您可能會遇到以下常見問題:

1. 認證失敗

問題: Error: Your request could not be authenticated

解決方案:

  • 確認 GitHub Secrets 中的 DockerHub 憑證是否正確
  • 檢查 DockerHub 令牌是否過期(通常有效期為 1 年)
  • 確保令牌具有適當的權限(至少需要「Read & Write」權限)

2. 構建失敗

問題: 多平台構建失敗

解決方案:

  • 確保 Dockerfile 兼容所有目標平台
  • 使用條件構建指令處理平台特定的差異
  • 檢查依賴項是否支持所有目標架構

3. 映像大小問題

問題: Docker 映像過大

解決方案:

  • 使用多階段構建減小映像大小
  • 採用更輕量級的基礎映像(如 Alpine)
  • 清理構建過程中產生的臨時文件

GitHub Actions vs. 其他 CI/CD 工具

特性GitHub ActionsJenkinsCircleCIGitLab CI
與 GitHub 整合★★★★★★★★★★★★★★
配置難度
免費計劃限制2,000 分鐘/月自託管無限制6,000 分鐘/月400 分鐘/月
多平台支持原生支持插件支持有限支持有限支持
社區支持活躍非常活躍活躍活躍

結論

使用 GitHub Actions 自動化 Docker 映像的構建和發佈流程可以顯著提高開發效率、改善版本控制並簡化發布流程。Urusai 專案的工作流程展示了一個優化的自動化過程,該過程在推送版本標籤時觸發,生成多平台映像,並將其發佈到 Docker Hub。

在實踐自動化 Docker 映像發佈流程的同時,我們不能忽視安全性的重要性。定期審計和解決依賴項漏洞是維護健康軟體專案的關鍵。即使是小型專案,也應該定期使用 Dependabot 等工具來監控和解決漏洞,確保專案的安全性。

透過採用本文介紹的自動化工作流程,開發人員可以專注於代碼開發和功能實現,而將繁瑣的構建、標記、漏洞掃描和發佈任務交給自動化系統處理。這種方法不僅提高了效率,還減少了人為錯誤,確保了更一致、更安全、更可靠的發布過程。

最後,讓我們記住:自動化不僅是為了提高效率,也是為了增強軟體的質量和安全性。定期更新和維護您的 CI/CD 流程,就像更新您的代碼一樣重要。

參考資源

感謝您閱讀我的文章。歡迎隨時分享你的想法。
關於 Calpa

Calpa 擅長使用 TypeScriptReact.jsVue.js 建立 Responsive Website。

他積極參與開源社區,曾在 2019 年的香港開源大會上擔任講者,提供工作經驗和見解。此外,他也在 GitHub 上公開分享個人博客程式碼,已獲得超過 300 顆星星和 60 個分支的支持。

他熱愛學習新技術,並樂意分享經驗。他相信,唯有不斷學習才能跟上快速演變的技術環境。