mirror of
https://github.com/sredevopsorg/deepseek-kubernetes-sandbox.git
synced 2026-11-03 01:13:24 +00:00
Add multi-arch Docker image build workflow with GitHub Actions
This commit is contained in:
276
.github/workflows/multi-build-gateway.yaml
vendored
Normal file
276
.github/workflows/multi-build-gateway.yaml
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
# This workflow builds a multi-arch Docker image using GitHub Actions and separated Github Runners with native support for ARM64 and AMD64 architectures, without using QEMU emulation.
|
||||
# It uses Docker Buildx to build and push the image to GitHub Container Registry (GHCR).
|
||||
name: Gateway Build multi arch Docker Image with separate Github Runners
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'examples/dsh-agents-as-a-service/gateway/**'
|
||||
- '.github/workflows/multi-build-gateway.yaml'
|
||||
env:
|
||||
# The name of the Docker image to be built and pushed to GHCR
|
||||
# The image name is derived from the GitHub repository name and the GitHub Container Registry (GHCR) URL.
|
||||
# The image name will be in the format: ghcr.io/<owner>/<repo>
|
||||
GHCR_IMAGE: ghcr.io/${{ github.repository }}
|
||||
permissions:
|
||||
# Global permissions for the workflow, which can be overridden at the job level
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
# This concurrency group ensures that only one job in the group runs at a time.
|
||||
# If a new job is triggered, the previous one will be canceled.
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# The build job builds the Docker image for each platform specified in the matrix.
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform:
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
# The matrix includes two platforms: linux/amd64 and linux/arm64.
|
||||
# The build job will run for each platform in the matrix.
|
||||
|
||||
permissions:
|
||||
# Permissions for the build job, which can be overridden at the step level
|
||||
# The permissions are set to allow the job to write to the GitHub Container Registry (GHCR) and read from the repository.
|
||||
attestations: write
|
||||
actions: read
|
||||
checks: write
|
||||
contents: write
|
||||
deployments: none
|
||||
id-token: write
|
||||
issues: read
|
||||
discussions: read
|
||||
packages: write
|
||||
pages: none
|
||||
pull-requests: read
|
||||
repository-projects: read
|
||||
security-events: read
|
||||
statuses: read
|
||||
|
||||
runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-latest' || matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' }}
|
||||
# The job runs on different runners based on the platform.
|
||||
# For linux/amd64, it runs on the latest Ubuntu runner.
|
||||
# For linux/arm64, it runs on an Ubuntu 24.04 ARM runner.
|
||||
# The runner is selected based on the platform specified in the matrix.
|
||||
|
||||
name: Build Docker image for ${{ matrix.platform }}
|
||||
|
||||
steps:
|
||||
-
|
||||
name: Prepare environment for current platform
|
||||
# This step sets up the environment for the current platform being built.
|
||||
# It replaces the '/' character in the platform name with '-' and sets it as an environment variable.
|
||||
# This is useful for naming artifacts and other resources that cannot contain '/'.
|
||||
# The environment variable PLATFORMS_PAIR will be used later in the workflow.
|
||||
id: prepare
|
||||
run: |
|
||||
platform=${{ matrix.platform }}
|
||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
# This step checks out the code from the repository.
|
||||
# It uses the actions/checkout action to clone the repository into the runner's workspace.
|
||||
|
||||
- name: Docker meta default
|
||||
# This step generates metadata for the Docker image.
|
||||
# It uses the docker/metadata-action to create metadata based on the repository information.
|
||||
# The metadata includes information such as the image name, tags, and labels.
|
||||
# The metadata will be used later in the workflow to build and push the Docker image.
|
||||
id: meta
|
||||
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
|
||||
with:
|
||||
images: ${{ env.GHCR_IMAGE }}
|
||||
tags: |
|
||||
type=raw,value=gateway
|
||||
|
||||
|
||||
- name: Set up Docker Context for Buildx
|
||||
# This step sets up a Docker context for Buildx.
|
||||
# It creates a new context named "builders" that will be used for building the Docker image.
|
||||
# The context allows Buildx to use the Docker daemon for building images.
|
||||
id: buildx-context
|
||||
run: |
|
||||
docker context create builders
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
# This step sets up Docker Buildx, which is a Docker CLI plugin for extended build capabilities with BuildKit.
|
||||
# It uses the docker/setup-buildx-action to configure Buildx with the specified context and platforms.
|
||||
# The platforms are specified in the matrix and will be used for building the Docker image.
|
||||
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
|
||||
with:
|
||||
endpoint: builders
|
||||
platforms: ${{ matrix.platform }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
# This step logs in to the GitHub Container Registry (GHCR) using the docker/login-action.
|
||||
# It uses the GitHub actor's username and the GITHUB_TOKEN secret for authentication.
|
||||
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
- name: Build and push by digest
|
||||
# This step builds and pushes the Docker image using Buildx.
|
||||
# It uses the docker/build-push-action to build the image with the specified context and platforms.
|
||||
# The image is built with the labels and annotations generated in the previous steps.
|
||||
# The outputs are configured to push the image by digest, which allows for better caching and versioning.
|
||||
# The cache-from and cache-to options are used to enable caching for the build process.
|
||||
# The cache is stored in GitHub Actions cache and is scoped to the repository, branch, and platform.
|
||||
id: build
|
||||
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
||||
env:
|
||||
DOCKER_BUILDKIT: 1
|
||||
with:
|
||||
context: ./examples/dsh-agents-as-a-service/gateway/
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
annotations: ${{ steps.meta.outputs.annotations }}
|
||||
outputs: type=image,name=${{ env.GHCR_IMAGE }},push-by-digest=true,name-canonical=true,push=true,oci-mediatypes=true
|
||||
cache-from: type=gha,scope=${{ github.repository }}-${{ github.ref_name }}-${{ matrix.platform }}
|
||||
cache-to: type=gha,scope=${{ github.repository }}-${{ github.ref_name }}-${{ matrix.platform }}
|
||||
|
||||
|
||||
- name: Export digest
|
||||
# This step exports the digest of the built image to a file.
|
||||
# It creates a directory in /tmp/digests and saves the digest of the image to a file.
|
||||
# The digest is obtained from the output of the build step.
|
||||
# The digest is used to uniquely identify the built image and can be used for further processing or verification.
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "/tmp/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
# This step uploads the digest file to the GitHub Actions artifact storage.
|
||||
# It uses the actions/upload-artifact action to upload the file created in the previous step.
|
||||
# The artifact is named digests-${{ env.PLATFORM_PAIR }}, where PLATFORM_PAIR is the platform name with '/' replaced by '-'.
|
||||
# The artifact is retained for 1 day, and if no files are found, it will throw an error.
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: /tmp/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
|
||||
merge:
|
||||
# This job merges the Docker manifests for the different platforms built in the previous job.
|
||||
name: Merge Docker manifests
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
attestations: write
|
||||
actions: read
|
||||
checks: read
|
||||
contents: read
|
||||
deployments: none
|
||||
id-token: write
|
||||
issues: read
|
||||
discussions: read
|
||||
packages: write
|
||||
pages: none
|
||||
pull-requests: read
|
||||
repository-projects: read
|
||||
security-events: read
|
||||
statuses: read
|
||||
|
||||
needs:
|
||||
- build
|
||||
# This job depends on the build job to complete before it starts.
|
||||
# It ensures that the Docker images for all platforms are built before merging the manifests.
|
||||
steps:
|
||||
- name: Download digests
|
||||
# This step downloads the digest files uploaded in the build job.
|
||||
# It uses the actions/download-artifact action to download the artifacts with the pattern digests-*.
|
||||
# The downloaded files are merged into the /tmp/digests directory.
|
||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
|
||||
|
||||
- name: Docker meta
|
||||
# This step generates metadata for the Docker image.
|
||||
# It uses the docker/metadata-action to create metadata based on the repository information.
|
||||
# The metadata includes information such as the image name, tags, and labels.
|
||||
id: meta
|
||||
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
|
||||
with:
|
||||
images: ${{ env.GHCR_IMAGE }}
|
||||
annotations: |
|
||||
type=org.opencontainers.image.description,value=${{ github.event.repository.description || 'No description provided' }}
|
||||
tags: |
|
||||
type=raw,value=gateway
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
|
||||
# This step sets up Docker Buildx, which is a Docker CLI plugin for extended build capabilities with BuildKit.
|
||||
with:
|
||||
driver-opts: |
|
||||
network=host
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
||||
# This step logs in to the GitHub Container Registry (GHCR) using the docker/login-action.
|
||||
# It uses the GitHub actor's username and the GITHUB_TOKEN secret for authentication.
|
||||
# The login is necessary to push the merged manifest list to GHCR.
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get execution timestamp with RFC3339 format
|
||||
# This step gets the current execution timestamp in RFC3339 format.
|
||||
# It uses the date command to get the current UTC time and formats it as a string.
|
||||
# The timestamp is used for annotating the Docker manifest list.
|
||||
id: timestamp
|
||||
run: |
|
||||
echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create manifest list and pushs
|
||||
# This step creates a manifest list for the Docker images built for different platforms.
|
||||
# It uses the docker buildx imagetools create command to create the manifest list.
|
||||
# The manifest list is annotated with metadata such as description, creation timestamp, and source URL.
|
||||
# The annotations are obtained from the metadata generated in the previous steps.
|
||||
# The manifest list is pushed to the GitHub Container Registry (GHCR) with the specified tags.
|
||||
working-directory: /tmp/digests
|
||||
id: manifest-annotate
|
||||
continue-on-error: true
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
--annotation='index:org.opencontainers.image.description=${{ github.event.repository.description }}' \
|
||||
--annotation='index:org.opencontainers.image.created=${{ steps.timestamp.outputs.timestamp }}' \
|
||||
--annotation='index:org.opencontainers.image.url=${{ github.event.repository.url }}' \
|
||||
--annotation='index:org.opencontainers.image.source=${{ github.event.repository.url }}' \
|
||||
$(printf '${{ env.GHCR_IMAGE }}@sha256:%s ' *)
|
||||
|
||||
- name: Create manifest list and push without annotations
|
||||
# This step creates a manifest list for the Docker images built for different platforms.
|
||||
# It uses the docker buildx imagetools create command to create the manifest list.
|
||||
# The manifest list is created without annotations if the previous step fails.
|
||||
# The manifest list is pushed to the GitHub Container Registry (GHCR) with the specified tags.
|
||||
if: steps.manifest-annotate.outcome == 'failure'
|
||||
working-directory: /tmp/digests
|
||||
run: |
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
$(printf '${{ env.GHCR_IMAGE }}@sha256:%s ' *)
|
||||
|
||||
- name: Inspect image
|
||||
# This step inspects the created manifest list to verify its contents.
|
||||
# It uses the docker buildx imagetools inspect command to display information about the manifest list.
|
||||
# The inspection output will show the platforms and tags associated with the manifest list.
|
||||
id: inspect
|
||||
run: |
|
||||
docker buildx imagetools inspect '${{ env.GHCR_IMAGE }}:${{ steps.meta.outputs.version }}'
|
||||
Reference in New Issue
Block a user