From de27230b7ab97c1ef92d6b4854b1982e843c4123 Mon Sep 17 00:00:00 2001 From: yyhuni Date: Sat, 3 Jan 2026 18:28:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=9E=84=E5=BB=BAci?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-build.yml | 176 ++++++++++++++++++++++------- 1 file changed, 136 insertions(+), 40 deletions(-) diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index df2dadc4..f376ca0f 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -19,7 +19,8 @@ permissions: contents: write jobs: - build: + # AMD64 构建(原生 x64 runner) + build-amd64: runs-on: ubuntu-latest strategy: matrix: @@ -27,43 +28,30 @@ jobs: - image: xingrin-server dockerfile: docker/server/Dockerfile context: . - platforms: linux/amd64,linux/arm64 - image: xingrin-frontend dockerfile: docker/frontend/Dockerfile context: . - platforms: linux/amd64 # ARM64 构建时 Next.js 在 QEMU 下会崩溃 - image: xingrin-worker dockerfile: docker/worker/Dockerfile context: . - platforms: linux/amd64,linux/arm64 - image: xingrin-nginx dockerfile: docker/nginx/Dockerfile context: . - platforms: linux/amd64,linux/arm64 - image: xingrin-agent dockerfile: docker/agent/Dockerfile context: . - platforms: linux/amd64,linux/arm64 - image: xingrin-postgres dockerfile: docker/postgres/Dockerfile context: docker/postgres - platforms: linux/amd64,linux/arm64 steps: - name: Checkout uses: actions/checkout@v4 - - name: Free disk space (for large builds like worker) + - name: Free disk space run: | - echo "=== Before cleanup ===" - df -h - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/lib/android - sudo rm -rf /opt/ghc - sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL sudo docker image prune -af - echo "=== After cleanup ===" - df -h - name: Generate SSL certificates for nginx build if: matrix.image == 'xingrin-nginx' @@ -73,10 +61,6 @@ jobs: -keyout docker/nginx/ssl/privkey.pem \ -out docker/nginx/ssl/fullchain.pem \ -subj "/CN=localhost" - echo "SSL certificates generated for CI build" - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -87,7 +71,120 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Get version from git tag + - name: Get version + id: version + run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + else + echo "VERSION=dev-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + fi + + - name: Build and push AMD64 + uses: docker/build-push-action@v5 + with: + context: ${{ matrix.context }} + file: ${{ matrix.dockerfile }} + platforms: linux/amd64 + push: true + tags: ${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:${{ steps.version.outputs.VERSION }}-amd64 + build-args: IMAGE_TAG=${{ steps.version.outputs.VERSION }} + cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:cache-amd64 + cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:cache-amd64,mode=max + provenance: false + sbom: false + + # ARM64 构建(原生 ARM64 runner) + build-arm64: + runs-on: ubuntu-22.04-arm + strategy: + matrix: + include: + - image: xingrin-server + dockerfile: docker/server/Dockerfile + context: . + - image: xingrin-frontend + dockerfile: docker/frontend/Dockerfile + context: . + - image: xingrin-worker + dockerfile: docker/worker/Dockerfile + context: . + - image: xingrin-nginx + dockerfile: docker/nginx/Dockerfile + context: . + - image: xingrin-agent + dockerfile: docker/agent/Dockerfile + context: . + - image: xingrin-postgres + dockerfile: docker/postgres/Dockerfile + context: docker/postgres + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Generate SSL certificates for nginx build + if: matrix.image == 'xingrin-nginx' + run: | + mkdir -p docker/nginx/ssl + openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout docker/nginx/ssl/privkey.pem \ + -out docker/nginx/ssl/fullchain.pem \ + -subj "/CN=localhost" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Get version + id: version + run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + else + echo "VERSION=dev-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + fi + + - name: Build and push ARM64 + uses: docker/build-push-action@v5 + with: + context: ${{ matrix.context }} + file: ${{ matrix.dockerfile }} + platforms: linux/arm64 + push: true + tags: ${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:${{ steps.version.outputs.VERSION }}-arm64 + build-args: IMAGE_TAG=${{ steps.version.outputs.VERSION }} + cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:cache-arm64 + cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:cache-arm64,mode=max + provenance: false + sbom: false + + # 合并多架构 manifest + merge-manifests: + runs-on: ubuntu-latest + needs: [build-amd64, build-arm64] + strategy: + matrix: + image: + - xingrin-server + - xingrin-frontend + - xingrin-worker + - xingrin-nginx + - xingrin-agent + - xingrin-postgres + steps: + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Get version id: version run: | if [[ $GITHUB_REF == refs/tags/* ]]; then @@ -98,28 +195,27 @@ jobs: echo "IS_RELEASE=false" >> $GITHUB_OUTPUT fi - - name: Build and push - uses: docker/build-push-action@v5 - with: - context: ${{ matrix.context }} - file: ${{ matrix.dockerfile }} - platforms: ${{ matrix.platforms }} - push: true - tags: | - ${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:${{ steps.version.outputs.VERSION }} - ${{ steps.version.outputs.IS_RELEASE == 'true' && format('{0}/{1}:latest', env.IMAGE_PREFIX, matrix.image) || '' }} - build-args: | - IMAGE_TAG=${{ steps.version.outputs.VERSION }} - cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:cache - cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/${{ matrix.image }}:cache,mode=max - provenance: false - sbom: false + - name: Create and push multi-arch manifest + run: | + VERSION=${{ steps.version.outputs.VERSION }} + IMAGE=${{ env.IMAGE_PREFIX }}/${{ matrix.image }} + + docker manifest create ${IMAGE}:${VERSION} \ + ${IMAGE}:${VERSION}-amd64 \ + ${IMAGE}:${VERSION}-arm64 + docker manifest push ${IMAGE}:${VERSION} + + if [[ "${{ steps.version.outputs.IS_RELEASE }}" == "true" ]]; then + docker manifest create ${IMAGE}:latest \ + ${IMAGE}:${VERSION}-amd64 \ + ${IMAGE}:${VERSION}-arm64 + docker manifest push ${IMAGE}:latest + fi - # 所有镜像构建成功后,更新 VERSION 文件 - # 根据 tag 所在的分支更新对应分支的 VERSION 文件 + # 更新 VERSION 文件 update-version: runs-on: ubuntu-latest - needs: build + needs: merge-manifests if: startsWith(github.ref, 'refs/tags/v') steps: - name: Checkout repository