如何使用 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。

comments powered by Disqus

相關文章

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

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

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

閱讀更多
使用 asdf 工具有效管理 Elixir、Erlang、Python 和 Node.js 等多種程式語言的版本

使用 asdf 工具有效管理 Elixir、Erlang、Python 和 Node.js 等多種程式語言的版本

在軟體開發領域中,維持團隊成員工具版本的一致性是非常關鍵的。這正是 asdf 版本管理工具發揮作用的時刻。 asdf 讓你能在一個文件( .tool-versions )裡面指定所有工具的版

閱讀更多
壓縮大師:使用 7-Zip 輕鬆個別壓縮多個資料夾

壓縮大師:使用 7-Zip 輕鬆個別壓縮多個資料夾

7-Zip 是一款開源的壓縮軟件,支持包括 7z、XZ、BZIP2、GZIP、TAR、ZIP、WIM 等多種壓縮格式。它提供了圖形用戶界面和右鍵選單,但並

閱讀更多