name: Docker Build Multi-Arch
on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: '版本标签 (例如: v1.0.0)'
required: true
default: 'v0.2.8'
also_latest:
description: '同时推送为latest标签'
type: boolean
required: true
default: true
permissions:
contents: read packages: write
jobs:
build-amd64:
runs-on: ubuntu-latest
outputs:
digest: ${{ steps.build_push_amd64.outputs.digest }}
steps:
- name: Checkout
uses: actions/checkout@v4 with:
fetch-depth: 0
- name: Docker meta amd64
id: meta_amd64
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}
tags: |
# Git tag 推送时使用,添加 -amd64 后缀
type=ref,event=tag,suffix=-amd64
type=raw,value=${{ github.event.release.tag_name }}-amd64,enable=${{ github.event_name == 'release' }}
# 手动触发时使用输入的版本,添加 -amd64 后缀
type=raw,value=${{ github.event.inputs.version }}-amd64,enable=${{ github.event_name == 'workflow_dispatch' }}
- name: Set up QEMU uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push amd64
id: build_push_amd64 uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile
push: true
platforms: linux/amd64 tags: ${{ steps.meta_amd64.outputs.tags }}
labels: ${{ steps.meta_amd64.outputs.labels }}
load: false
cache-from: type=gha
cache-to: type=gha,mode=max
build-arm64:
runs-on: ubuntu-24.04-arm outputs:
digest: ${{ steps.build_push_arm64.outputs.digest }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Docker meta arm64
id: meta_arm64
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}
tags: |
# Git tag 推送时使用,添加 -arm64 后缀
type=ref,event=tag,suffix=-arm64
type=raw,value=${{ github.event.release.tag_name }}-arm64,enable=${{ github.event_name == 'release' }}
# 手动触发时使用输入的版本,添加 -arm64 后缀
type=raw,value=${{ github.event.inputs.version }}-arm64,enable=${{ github.event_name == 'workflow_dispatch' }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push arm64
id: build_push_arm64 uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile
push: true
platforms: linux/arm64 tags: ${{ steps.meta_arm64.outputs.tags }}
labels: ${{ steps.meta_arm64.outputs.labels }}
load: false
cache-from: type=gha
cache-to: type=gha,mode=max
push-manifest:
runs-on: ubuntu-latest
needs: [build-amd64, build-arm64] steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create and push manifest
run: |
REPO_OWNER=$(echo "$GITHUB_REPOSITORY_OWNER" | tr '[:upper:]' '[:lower:]')
REPO_NAME="${GITHUB_REPOSITORY#*/}"
image_base_ghcr="ghcr.io/${REPO_OWNER}/${REPO_NAME}"
image_base_dockerhub="${{ secrets.DOCKERHUB_USERNAME }}/${REPO_NAME}"
echo "Raw tags output"
if [[ "${{ github.event_name }}" == "push" && "$GITHUB_REF" =~ ^refs/tags/ ]] || [[ "${{ github.event_name }}" == "release" ]]; then
# 获取标签名称(从push事件或release事件)
if [[ "${{ github.event_name }}" == "push" ]]; then
VERSION="${{ github.ref_name }}"
else
VERSION="${{ github.event.release.tag_name }}"
fi
docker buildx imagetools create -t \
${image_base_ghcr}:${VERSION} \
${image_base_ghcr}:${VERSION}-arm64 \
${image_base_ghcr}:${VERSION}-amd64
docker buildx imagetools create -t \
${image_base_dockerhub}:${VERSION} \
${image_base_dockerhub}:${VERSION}-arm64 \
${image_base_dockerhub}:${VERSION}-amd64
# 如果是release,则设置latest标签
if [[ "${{ github.event_name }}" == "release" ]]; then
docker buildx imagetools create -t \
${image_base_ghcr}:latest \
${image_base_ghcr}:${VERSION}-arm64 \
${image_base_ghcr}:${VERSION}-amd64
docker buildx imagetools create -t \
${image_base_dockerhub}:latest \
${image_base_dockerhub}:${VERSION}-arm64 \
${image_base_dockerhub}:${VERSION}-amd64
fi
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
docker buildx imagetools create -t \
${image_base_ghcr}:${{ github.event.inputs.version }} \
${image_base_ghcr}:${{ github.event.inputs.version }}-arm64 \
${image_base_ghcr}:${{ github.event.inputs.version }}-amd64
docker buildx imagetools create -t \
${image_base_dockerhub}:${{ github.event.inputs.version }} \
${image_base_dockerhub}:${{ github.event.inputs.version }}-arm64 \
${image_base_dockerhub}:${{ github.event.inputs.version }}-amd64
if [ "${{ github.event.inputs.also_latest }}" == "true" ]; then
docker buildx imagetools create -t \
${image_base_ghcr}:latest \
${image_base_ghcr}:${{ github.event.inputs.version }}-arm64 \
${image_base_ghcr}:${{ github.event.inputs.version }}-amd64
docker buildx imagetools create -t \
${image_base_dockerhub}:latest \
${image_base_dockerhub}:${{ github.event.inputs.version }}-arm64 \
${image_base_dockerhub}:${{ github.event.inputs.version }}-amd64
fi
fi
echo "Manifest push completed."
echo "Manifest for ${image_base_ghcr} and ${image_base_dockerhub} created and pushed successfully."