如何使用 GitHub Actions 自動建立並推送 Docker Image

如何使用 GitHub Actions 自動建立並推送 Docker Image

目錄

在我們先前的文章 中,我們學習了如何使用 buildx 來建立能在多平台運行的 Docker Image。然而,這種方法仍需要手動操作。為了讓我們能在 Hugo 有新版本更新時自動建立對應的 Docker Image,我們可以利用 GitHub Actions 來實現這個目標。

建立 GitHub Actions

GitHub Action 是 GitHub 提供的一種自動化工具,我們可以在 GitHub Repository 中創建一個 .github/workflows 目錄,並在其中創建一個 .yml 檔案,即可利用 GitHub Action 自動化執行一些任務。

今天我們的目標是利用 GitHub Action 自動建立 Docker Image。因此,我們首先在 .github/workflows 目錄中創建一個名為 build.yml 的檔案,並填入以下內容:

name: Check Hugo Release & Publish to Docker Hub

on:
  schedule:
    - cron: "0 0 * * *" # 每天檢查一次
  push:
    branches:
      - main

jobs:
  check-and-publish:
    runs-on: ubuntu-latest

    steps:
      - name: Install jq
        run: |
          sudo apt-get install jq
          echo "jq installed successfully."          

      - name: Check for Hugo new release
        id: check-release
        run: |
          ver=$(curl --silent "https://api.github.com/repos/gohugoio/hugo/releases/latest" | jq -r .tag_name)
          echo "Latest Hugo version: $ver"
          echo "HUGO_VERSION=$ver" >> $GITHUB_ENV          

      - name: Check if version exists on Docker Hub
        run: |
          tags=$(curl -s "https://registry.hub.docker.com/v2/repositories/${{ secrets.DOCKERHUB_USERNAME }}/hugo/tags/" | jq -r '.results[].name')
          if echo "$tags" | grep -q "${HUGO_VERSION#v}-ext-debian"; then
            echo "Version already exists on Docker Hub."
            echo "DO_BUILD=false" >> $GITHUB_ENV
          else
            echo "Version does not exist on Docker Hub."
            echo "DO_BUILD=true" >> $GITHUB_ENV
          fi          

      - name: Checkout code
        if: env.DO_BUILD == 'true'
        uses: actions/checkout@v2

      - name: Login to Docker Hub
        if: env.DO_BUILD == 'true'
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_PASSWORD }}

      - name: Build and push
        if: env.DO_BUILD == 'true'
        run: |
          username=${{ secrets.DOCKERHUB_USERNAME }}
          echo "Docker Hub username: $username"
          ver=${HUGO_VERSION#v}
          echo "Stripped Hugo version: $ver"
          builder=builder
          if ! docker buildx ls | grep -q $builder; then
              docker buildx create --name $builder
              echo "Builder $builder created."
          else
              echo "Builder $builder already exists."
          fi
          docker buildx use $builder
          echo "Using builder: $builder"
          docker buildx inspect --bootstrap
          docker buildx build --platform=linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7 --push -t $username/hugo:$ver-ext-debian -t $username/hugo:latest .
          echo "Docker image built and pushed successfully."          

總的來說,這個 GitHub Action 的工作流程是在每天的 00:00 時檢查 Hugo 是否有新的版本釋出。如果有,它將自動建立對應版本的 Docker Image,並將其推送到 Docker Hub 上。

配置 GitHub Action

在 GitHub Action 的設定中,我們可以指定觸發 GitHub Action 的條件。在這裡,我們設定了兩種觸發條件:schedulepush

  • schedule:每天的 00:00 時執行
  • push:當在 main 分支有新的提交時執行

為了避免每次觸發 GitHub Action 都重新推送 Docker Image,我們添加了一個步驟:Check if version exists on Docker Hub。此步驟會檢查 Docker Hub 上是否已有相同版本的 Docker Image,如果已存在,則不會再重新建立 Docker Image。

使用 GitHub Action 的 Secrets

在 GitHub Action 中,我們可以利用 Secrets 來儲存敏感資訊,如 Docker Hub 的帳號和密碼。這樣,我們就不需要在 GitHub Action 的設定中直接寫入帳號和密碼,而是使用 Secrets 來儲存,進而避免帳號和密碼的外洩風險。

值得一提的是,由於 Hugo 的 Repository 有時會在一天內釋出多個補丁版本,因此以每天檢查一次的頻率可能會有遺漏。然而,我認為對於大多數使用者來說,這樣的頻率應該已經足夠了。

如果你有任何建議或問題,歡迎在我的 GitHub 上提出 issue。

相關文章

如何快速建置 Node.js 專案並使用 TypeScript 與 Visual Studio Code 進行開發

如何快速建置 Node.js 專案並使用 TypeScript 與 Visual Studio Code 進行開發

安裝 .NET CLI on Windows with Chocolatey choco install dotnetcore-sdk -y on macOS with Homebrew brew install dotnet-sdk on Ubuntu sudo apt-get install dotnet-sdk -y 使用 Will 保哥 的專案範本建立一個新的 TypeScript 專案 安裝專案範本 dotnet new --install Duotify.Templates.DotNetNew 建立新的 TypeScript 專案 mkdir <project-folder> && cd <project-folder> dotnet new tsnode

閱讀更多
使用 Chocolatey 快速安裝和管理 Windows 軟體

使用 Chocolatey 快速安裝和管理 Windows 軟體

作為一名熟悉 Linux 或 MacOS 的用戶,我們習慣於使用命令列工具來管理軟體。長久以來,Windows 缺少了這樣的工具,直到 Chocolatey 的出現。Chocolatey 為

閱讀更多
深入了解 C 語言的 printf 函數:格式化輸出技巧

深入了解 C 語言的 printf 函數:格式化輸出技巧

C 語言中的 printf 函數是一種非常強大的工具,用於在終端或其他輸出流中顯示格式化的文字。本文將詳細介紹如何使用 printf 進行高級格式化,特別是如何控制輸出的

閱讀更多