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

分享 :

相關文章

使用 Docker buildx 建立多平台 Docker Image

使用 Docker buildx 建立多平台 Docker Image

最近我在建設我的網站時選擇了 Hugo 這款靜態網站生成器,並選用了 Blowfish 主題。然而,我面臨了一個挑戰:Blowfish 主題要求 Hugo 的版本至少為 v0.115.0,但官方在 Docker Hub 上推薦的版本僅更新到了 v0.111.3。經過一番搜索,未能找到合適的 Docker Image,於是我決定自行創建一個。

閱讀更多
如何解決 git ssh key permission denied (publickey) 的錯誤

如何解決 git ssh key permission denied (publickey) 的錯誤

最近在設定 git ssh-key 時發生了 Permission denied (publickey) 的問題。雖然網路上有很多相關的解決方案,但是都沒有解決我的問題。因此在這邊紀錄一下我遇到的問題及解決方案。 已經確認 .ssh 資料夾裡面已經有 key 了,也在 GitHub 上正確設定了,在其他電腦運作都沒問題。但是在這台電腦上卻一直出現 Permission denied (publickey) 的錯誤。

閱讀更多