Files
nofx/.github/workflows/docker-build.yml
T
SkywalkerJi 22731189bd fix: Increase Docker build speed by 98%. (#545)
* Resolved front-end linting issues.
* Streamlining Docker Build Scripts
* Leveraging Native ARM64 Runners on GitHub.
* Use lowercase framework names.
2025-11-05 22:24:56 +08:00

194 lines
6.6 KiB
YAML

name: Build and Push Docker Images
on:
push:
branches:
- main
- dev
tags:
- 'v*'
workflow_dispatch:
env:
REGISTRY_GHCR: ghcr.io
jobs:
# 预处理: 转换镜像名为小写
prepare:
runs-on: ubuntu-22.04
outputs:
image_base: ${{ steps.lowercase.outputs.image_base }}
steps:
- name: Convert repository name to lowercase
id: lowercase
run: |
REPO_LOWER=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
echo "image_base=${REPO_LOWER}" >> $GITHUB_OUTPUT
echo "Lowercase repository: ${REPO_LOWER}"
# 并行构建策略: 使用原生架构 runner 提升速度
# GitHub Actions 现在支持原生 ARM64 runner (ubuntu-22.04-arm)
build-and-push:
needs: prepare
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
strategy:
# 并行运行所有构建任务
fail-fast: false
matrix:
include:
# Backend builds
- name: backend
dockerfile: ./docker/Dockerfile.backend
image_suffix: backend
platform: linux/amd64
arch_tag: amd64
runner: ubuntu-22.04
- name: backend
dockerfile: ./docker/Dockerfile.backend
image_suffix: backend
platform: linux/arm64
arch_tag: arm64
runner: ubuntu-22.04-arm # 原生 ARM64 runner
# Frontend builds
- name: frontend
dockerfile: ./docker/Dockerfile.frontend
image_suffix: frontend
platform: linux/amd64
arch_tag: amd64
runner: ubuntu-22.04
- name: frontend
dockerfile: ./docker/Dockerfile.frontend
image_suffix: frontend
platform: linux/arm64
arch_tag: arm64
runner: ubuntu-22.04-arm # 原生 ARM64 runner
steps:
- name: Checkout code
uses: actions/checkout@v4
# 原生 ARM64 runner 不需要 QEMU 模拟
# 只在需要时设置 QEMU (理论上不需要,因为是原生构建)
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY_GHCR }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
continue-on-error: true
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.REGISTRY_GHCR }}/${{ needs.prepare.outputs.image_base }}/nofx-${{ matrix.image_suffix }}
${{ secrets.DOCKERHUB_USERNAME && format('{0}/nofx-{1}', secrets.DOCKERHUB_USERNAME, matrix.image_suffix) || '' }}
tags: |
type=ref,event=branch,suffix=-${{ matrix.arch_tag }}
type=semver,pattern={{version}},suffix=-${{ matrix.arch_tag }}
type=semver,pattern={{major}}.{{minor}},suffix=-${{ matrix.arch_tag }}
type=sha,prefix={{branch}}-,suffix=-${{ matrix.arch_tag }}
- name: Build and push ${{ matrix.name }}-${{ matrix.arch_tag }} image
uses: docker/build-push-action@v5
with:
context: .
file: ${{ matrix.dockerfile }}
# 单独构建每个架构,4 个任务并行运行
platforms: ${{ matrix.platform }}
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# 使用架构特定的缓存
cache-from: type=gha,scope=${{ matrix.name }}-${{ matrix.arch_tag }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}-${{ matrix.arch_tag }}
build-args: |
BUILD_DATE=${{ github.event.head_commit.timestamp }}
VCS_REF=${{ github.sha }}
VERSION=${{ github.ref_name }}
- name: Image digest
run: |
echo "✅ Built: ${{ matrix.name }}-${{ matrix.arch_tag }}"
echo "Platform: ${{ matrix.platform }}"
echo "Tags: ${{ steps.meta.outputs.tags }}"
# 合并多架构镜像为统一 manifest
create-manifest:
needs: [prepare, build-and-push]
runs-on: ubuntu-22.04
permissions:
contents: read
packages: write
strategy:
matrix:
image_suffix: [backend, frontend]
steps:
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY_GHCR }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
continue-on-error: true
- name: Create and push multi-arch manifest
run: |
# 提取分支/标签名
REF_NAME="${{ github.ref_name }}"
# GHCR manifest (使用小写仓库名)
REPO_LOWER="${{ needs.prepare.outputs.image_base }}"
GHCR_IMAGE="${{ env.REGISTRY_GHCR }}/${REPO_LOWER}/nofx-${{ matrix.image_suffix }}"
echo "📦 Creating manifest for ${{ matrix.image_suffix }}..."
echo "Repository: ${REPO_LOWER}"
echo "Image: ${GHCR_IMAGE}"
# 创建并推送 manifest (合并 amd64 和 arm64)
docker buildx imagetools create -t "${GHCR_IMAGE}:${REF_NAME}" \
"${GHCR_IMAGE}:${REF_NAME}-amd64" \
"${GHCR_IMAGE}:${REF_NAME}-arm64"
# 如果是主分支,也创建 latest 标签
if [[ "${{ github.ref }}" == "refs/heads/main" ]] || [[ "${{ github.ref }}" == "refs/heads/dev" ]]; then
docker buildx imagetools create -t "${GHCR_IMAGE}:latest" \
"${GHCR_IMAGE}:${REF_NAME}-amd64" \
"${GHCR_IMAGE}:${REF_NAME}-arm64"
echo "✅ Created latest tag"
fi
# Docker Hub manifest (如果配置了)
if [[ -n "${{ secrets.DOCKERHUB_USERNAME }}" ]]; then
DOCKERHUB_IMAGE="${{ secrets.DOCKERHUB_USERNAME }}/nofx-${{ matrix.image_suffix }}"
docker buildx imagetools create -t "${DOCKERHUB_IMAGE}:${REF_NAME}" \
"${DOCKERHUB_IMAGE}:${REF_NAME}-amd64" \
"${DOCKERHUB_IMAGE}:${REF_NAME}-arm64" || true
echo "✅ Created Docker Hub manifest"
fi
echo "🎉 Multi-arch manifest created successfully!"