使用Github Actions进行docker build
#coding
效果
建立了一个仓库,基本功能是当检测到仓库中存在dockerfile更新时,自动进行docker build。
镜像名称会以子文件夹的名称进行命名,而tag则会以git commit该dockerfile更新的comment设定。
另外,稍微改造一下这个方案,就可以实现其他项目的自动docker build了。
示例仓库:MyDockerImagePublic
构建结果:Packages
例如:
- repo
- sub_01
- dockerfile
- sub_02
- dockerfile
- dockerfile
在上面这种结构下,会建立
ghcr.io/pzweuj:commit1
ghcr.io/pzweuj/sub_01:commit2
ghcr.io/pzweuj/sub_02:commit3
配置
将下面的yml配置文件放置在仓库的
.github/workflows
文件夹下
配置文件参考
name: Build and Push Docker Images
on:
push:
paths:
- '**/[Dd]ockerfile'
- '**/Dockerfile*'
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
changed_files: ${{ steps.detect.outputs.changed_files }}
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Detect changed Dockerfiles
id: detect
run: |
echo "Current SHA: ${{ github.sha }}"
echo "Previous SHA: ${{ github.event.before }}"
# 显示所有变更的文件
echo "All changed files:"
git diff-tree --no-commit-id --name-only -r ${{ github.sha }}
# 尝试使用不同的git命令来检测变更
CHANGED_FILES=$(git diff-tree --no-commit-id --name-only -r ${{ github.sha }} | grep -i dockerfile || true)
echo "changed_files=${CHANGED_FILES}" >> $GITHUB_OUTPUT
- name: Extract Commit Message
id: extract_message
run: |
COMMIT_MSG=$(git log -1 --pretty=%B)
FORMATTED_MSG=$(echo "$COMMIT_MSG" | tr ' ' '-' | tr -d '\n' | tr -cd '[:alnum:]-')
echo "Commit Message: $FORMATTED_MSG"
echo "COMMIT_MESSAGE=$FORMATTED_MSG" >> $GITHUB_ENV
- name: Debug Output
run: |
echo "GITHUB_OUTPUT content:"
cat $GITHUB_OUTPUT
echo "Changed files value:"
echo "${{ steps.detect.outputs.changed_files }}"
build:
needs: detect-changes
if: ${{ contains(needs.detect-changes.outputs.changed_files, 'Dockerfile') }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GHCR_PAT }}
- name: Build and push images
run: |
# 获取 commit message 并清理特殊字符
VERSION="${{ github.event.head_commit.message }}"
# 移除特殊字符,只保留字母、数字、点、横杠和下划线
VERSION=$(echo "$VERSION" | tr -dc 'a-zA-Z0-9._-')
echo "Using version tag: $VERSION"
for file in ${{ needs.detect-changes.outputs.changed_files }}; do
echo "Building and pushing image for $file..."
dir=$(dirname $file)
docker build -t ghcr.io/pzweuj/$dir:$VERSION -t ghcr.io/pzweuj/$dir:latest -f $file .
echo "Pushing image ghcr.io/pzweuj/$dir:$VERSION"
docker push ghcr.io/pzweuj/$dir:$VERSION
docker push ghcr.io/pzweuj/$dir:latest
done
- name: Debug Changed Files
run: |
echo "Changed files from previous job:"
echo "${{ needs.detect-changes.outputs.changed_files }}"
环境变量
需要对这个仓库进行环境变量设置,因为我们需要将镜像推送到ghcr中,因此需要配置token。在仓库的设置中进行配置,避免token泄漏。
token获取
点击自己的头像 -> Settings -> Developer settings -> Personal access tokens -> Tokens(classic) -> Generate new token -> Generate new token(classic)
在验证账户后,仅勾选 “读”、“写”权限,token有效期最长可选择一年,生成后只会在页面显示一次,记得复制下来。
仓库配置
在仓库页面,点击上方的 Settings,然后选择左侧的 Secrets and variables -> Actions,添加一个Secrets,其中名称是GHCR_PAT,值是刚刚获取的token。保存后,这个仓库即可实现对传输进的dockerfile进行自动docker build的功能。