如何使用 GitHub Actions 自動建立並推送 Docker Image
- Leo
- 技術宅 ( tech geek)
- 2023年9月2日
目錄
在我們先前的文章
中,我們學習了如何使用 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 的條件。在這裡,我們設定了兩種觸發條件:schedule
和 push
。
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。