记录一次GithubActions优化(Docker构建)
利用GithubActions构建多平台兼容的Docker镜像时,执行起来总是很慢,让AI优化了一下任务配置文件~
渲染中...
## 主要改进点(做得好的地方)
1. Checkout 添加 `fetch-depth: 0`:改进前默认是浅克隆(`depth=1`),`git describe --tags` 经常无法正确获取历史 tag,导致版本号提取失败。添加 `fetch-depth: 0` 后可靠性显著提升。
2. 版本号输出方式改为 `$GITHUB_OUTPUT`:这是正确且推荐的做法。改进前用 `>> $GITHUB_ENV` 虽然也能工作,但 `GITHUB_OUTPUT` 是更现代、作用域更清晰的方式(尤其适合后续步骤引用)。
3. 切换到官方 `docker/build-push-action@v5`:这是最大、最重要的改进。
- 不再手动写 `docker buildx build ...` 命令,减少了语法错误风险。
- 自动处理多平台 manifest、推送、标签等。
- 代码更简洁、可读性更好。
4. 添加 `setup-qemu-action`:对于 `linux/arm64` 平台,在 `ubuntu-latest(x86_64)`上构建时需要 QEMU 模拟。改进前缺少这个步骤,arm64 构建很可能失败或非常慢。添加后多平台支持更完整。
5. 启用 Buildx 缓存(`cache-from + cache-to: type=gha,mode=max`):能显著加快后续构建速度,尤其是在多平台 + 多阶段 Dockerfile 的情况下。
6. 明确指定 `context: .` 和 `file: ./Dockerfile`:更清晰,虽然 `.` 是默认值,但写出来更好维护。
7. 使用 `steps.get_version.outputs.VERSION` 引用版本:配合 GITHUB_OUTPUT 使用。
## 原配置
```yaml
name: Docker
on:
push:
tags:
- v*.*.*
jobs:
docker_build:
environment: docker_hub
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get version
id: get_version
run: |
VERSION=$(git describe --tags --always --match 'v*' | sed -n 's|^v\([0-9]*\.[0-9]*\.[0-9]*\)\(-.*\)\{0,1\}|\1|p')
echo "VERSION=$VERSION" >> $GITHUB_ENV # Store version as an environment variable
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
# 设置 Docker Buildx (支持多平台构建)
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# 单次构建多平台镜像并推送
- name: Build and push multi-platform image
run: |
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag dingdangdog/jimily:${VERSION} \
--tag dingdangdog/jimily:latest \
--push .
- name: Clean up Docker images
run: docker system prune -af
```
## 新配置
```yaml
name: Docker
on:
push:
tags:
- v*.*.*
jobs:
docker_build:
environment: docker_hub
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # 确保能获取到 tags 用于生成版本号
- name: Get version
id: get_version
# 提取语义化版本号,例如从 v5.1.3 提取出 5.1.3
run: |
VERSION=$(git describe --tags --always --match 'v*' | sed -n 's|^v\([0-9]*\.[0-9]*\.[0-9]*\)\(-.*\)\{0,1\}|\1|p')
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: arm64 # 明确指定需要模拟的平台
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push multi-platform image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: |
dingdangdog/jimily:${{ steps.get_version.outputs.VERSION }}
dingdangdog/jimily:latest
# 关键改进:启用 GitHub Actions 缓存后端
cache-from: type=gha
cache-to: type=gha,mode=max
# 传递构建参数(如果你的 Dockerfile 需要 VERSION 变量可以开启下面这行)
# build-args: |
# APP_VERSION=${{ steps.get_version.outputs.VERSION }}
```END
评论
登录后查看和发表评论
前往登录