diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fb5656f..9d0efe5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -71,15 +71,19 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Build application image + - name: Build multi-platform application image uses: docker/build-push-action@v6 with: context: . file: ./Dockerfile push: false + platforms: linux/amd64,linux/arm64 tags: clawmanager:ci k8s-smoke: @@ -198,4 +202,3 @@ jobs: if [ -f /tmp/clawmanager-port-forward.pid ]; then kill "$(cat /tmp/clawmanager-port-forward.pid)" || true fi - diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 21b5945..a41f66e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,22 +27,38 @@ jobs: outputs: should_release: ${{ steps.decision.outputs.should_release }} tag_name: ${{ steps.decision.outputs.tag_name }} + image_fingerprint: ${{ steps.compute-fingerprint.outputs.image_fingerprint }} steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Build candidate image + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build amd64 candidate image shell: bash run: | - docker build --pull -t clawmanager:release-candidate . + docker buildx build --pull --platform linux/amd64 --load -t clawmanager:release-candidate-amd64 . + + - name: Build arm64 candidate image + shell: bash + run: | + docker buildx build --pull --platform linux/arm64 --load -t clawmanager:release-candidate-arm64 . - name: Compute release fingerprint + id: compute-fingerprint shell: bash run: | - IMAGE_FINGERPRINT="$(python3 .github/scripts/compute_image_fingerprint.py clawmanager:release-candidate)" + AMD64_FINGERPRINT="$(python3 .github/scripts/compute_image_fingerprint.py clawmanager:release-candidate-amd64)" + ARM64_FINGERPRINT="$(python3 .github/scripts/compute_image_fingerprint.py clawmanager:release-candidate-arm64)" + IMAGE_FINGERPRINT="$(printf '%s\n%s\n' "${AMD64_FINGERPRINT}" "${ARM64_FINGERPRINT}" | sha256sum | cut -d' ' -f1)" echo "IMAGE_FINGERPRINT=${IMAGE_FINGERPRINT}" >> "$GITHUB_ENV" + echo "image_fingerprint=${IMAGE_FINGERPRINT}" >> "$GITHUB_OUTPUT" - name: Read latest release fingerprint id: latest-release @@ -142,21 +158,33 @@ jobs: if: github.event_name != 'push' run: git checkout "${TAG_NAME}" + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Build release image + - name: Build amd64 release candidate shell: bash run: | - docker build --pull \ - -t "${IMAGE_URI}:${TAG_NAME}" \ - -t "${IMAGE_URI}:latest" \ - . + docker buildx build --pull --platform linux/amd64 --load -t clawmanager:release-candidate-amd64 . + + - name: Build arm64 release candidate + shell: bash + run: | + docker buildx build --pull --platform linux/arm64 --load -t clawmanager:release-candidate-arm64 . - name: Compute release fingerprint shell: bash run: | - IMAGE_FINGERPRINT="$(python3 .github/scripts/compute_image_fingerprint.py "${IMAGE_URI}:${TAG_NAME}")" + if [ -n "${{ needs.prepare-scheduled-release.outputs.image_fingerprint }}" ]; then + echo "IMAGE_FINGERPRINT=${{ needs.prepare-scheduled-release.outputs.image_fingerprint }}" >> "$GITHUB_ENV" + exit 0 + fi + + AMD64_FINGERPRINT="$(python3 .github/scripts/compute_image_fingerprint.py clawmanager:release-candidate-amd64)" + ARM64_FINGERPRINT="$(python3 .github/scripts/compute_image_fingerprint.py clawmanager:release-candidate-arm64)" + IMAGE_FINGERPRINT="$(printf '%s\n%s\n' "${AMD64_FINGERPRINT}" "${ARM64_FINGERPRINT}" | sha256sum | cut -d' ' -f1)" echo "IMAGE_FINGERPRINT=${IMAGE_FINGERPRINT}" >> "$GITHUB_ENV" - name: Log in to GHCR @@ -166,11 +194,16 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Push release image - shell: bash - run: | - docker push "${IMAGE_URI}:${TAG_NAME}" - docker push "${IMAGE_URI}:latest" + - name: Push multi-platform release image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: true + platforms: linux/amd64,linux/arm64 + tags: | + ${{ env.IMAGE_URI }}:${{ env.TAG_NAME }} + ${{ env.IMAGE_URI }}:latest - name: Read pushed image digest shell: bash @@ -197,6 +230,7 @@ jobs: Image: \`${IMAGE_URI}:${TAG_NAME}\` Latest: \`${IMAGE_URI}:latest\` + Platforms: \`linux/amd64\`, \`linux/arm64\` Image-Digest: \`${IMAGE_DIGEST}\` Build-Fingerprint: \`${IMAGE_FINGERPRINT}\` EOF diff --git a/Dockerfile b/Dockerfile index 37c9f5c..a896948 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20-alpine AS frontend-builder +FROM --platform=$BUILDPLATFORM node:20-alpine AS frontend-builder WORKDIR /app/frontend @@ -8,10 +8,13 @@ RUN npm ci COPY frontend/ ./ RUN npm run build -FROM golang:1.26.1-alpine AS backend-builder +FROM --platform=$BUILDPLATFORM golang:1.26.1-alpine AS backend-builder WORKDIR /app/backend +ARG TARGETOS +ARG TARGETARCH + ARG GOPROXY ARG GOSUMDB ARG GOFLAGS @@ -23,7 +26,7 @@ COPY backend/go.mod backend/go.sum ./ RUN go mod download COPY backend/ ./ -RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -buildvcs=false -ldflags="-s -w -buildid=" -o /out/clawreef-server ./cmd/server +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -trimpath -buildvcs=false -ldflags="-s -w -buildid=" -o /out/clawreef-server ./cmd/server FROM nginx:1.27-alpine diff --git a/docs/arm64-deployment.md b/docs/arm64-deployment.md index 20ef8be..7f861d9 100644 --- a/docs/arm64-deployment.md +++ b/docs/arm64-deployment.md @@ -6,18 +6,18 @@ ## 预构建 ARM64 镜像 -以下镜像已构建并发布到 GitHub Container Registry: +以下镜像可用于 ARM64 部署: | 镜像 | 地址 | 说明 | |------|------|------| -| ClawManager 主应用 | `ghcr.io/xty00/clawmanager:latest` | ARM64版本 | +| ClawManager 主应用 | `ghcr.io/yuan-lab-llm/clawmanager:latest` | 官方多架构镜像,包含 ARM64 | | Skill Scanner | `ghcr.io/xty00/skill-scanner:latest` | ARM64版本(官方原仓库无ARM64支持) | ### 使用预构建镜像 ```bash # 拉取ARM64镜像 -docker pull ghcr.io/xty00/clawmanager:latest --platform linux/arm64 +docker pull ghcr.io/yuan-lab-llm/clawmanager:latest --platform linux/arm64 docker pull ghcr.io/xty00/skill-scanner:latest --platform linux/arm64 ``` @@ -62,11 +62,11 @@ docker buildx build --platform linux/arm64 \ ### 修改镜像地址 -在 `clawmanager.yaml` 中将镜像地址替换为 ARM64 版本: +在 `clawmanager.yaml` 中确认镜像地址支持 ARM64: ```yaml # 主应用 -image: ghcr.io/xty00/clawmanager:latest +image: ghcr.io/yuan-lab-llm/clawmanager:latest # skill-scanner(如果需要) image: ghcr.io/xty00/skill-scanner:latest @@ -88,6 +88,12 @@ FLUSH PRIVILEGES; ## 已知问题 +### ClawManager 官方镜像支持 ARM64 + +- **状态**: `ghcr.io/yuan-lab-llm/clawmanager:latest` 发布为多架构镜像 +- **支持平台**: `linux/amd64`、`linux/arm64` +- **部署方式**: ARM64 节点会自动拉取对应架构镜像,无需单独维护主应用镜像地址 + ### skill-scanner 官方镜像无 ARM64 支持 - **问题**: `ghcr.io/yuan-lab-llm/skill-scanner:latest` 仅提供 amd64 平台 diff --git a/docs/arm64-deployment_en.md b/docs/arm64-deployment_en.md index 4d427d2..349bb49 100644 --- a/docs/arm64-deployment_en.md +++ b/docs/arm64-deployment_en.md @@ -6,18 +6,18 @@ This project supports deployment on ARM64 (aarch64) architecture devices such as ## Pre-built ARM64 Images -The following images have been built and published to GitHub Container Registry: +The following images can be used for ARM64 deployments: | Image | Address | Description | |-------|---------|-------------| -| ClawManager Main App | `ghcr.io/xty00/clawmanager:latest` | ARM64 version | +| ClawManager Main App | `ghcr.io/yuan-lab-llm/clawmanager:latest` | Official multi-platform image with ARM64 support | | Skill Scanner | `ghcr.io/xty00/skill-scanner:latest` | ARM64 version (official repo has no ARM64 support) | ### Using Pre-built Images ```bash # Pull ARM64 images -docker pull ghcr.io/xty00/clawmanager:latest --platform linux/arm64 +docker pull ghcr.io/yuan-lab-llm/clawmanager:latest --platform linux/arm64 docker pull ghcr.io/xty00/skill-scanner:latest --platform linux/arm64 ``` @@ -62,11 +62,11 @@ docker buildx build --platform linux/arm64 \ ### Modify Image Addresses -In `clawmanager.yaml`, replace image addresses with ARM64 versions: +In `clawmanager.yaml`, make sure the image addresses support ARM64: ```yaml # Main app -image: ghcr.io/xty00/clawmanager:latest +image: ghcr.io/yuan-lab-llm/clawmanager:latest # skill-scanner (if needed) image: ghcr.io/xty00/skill-scanner:latest @@ -88,6 +88,12 @@ FLUSH PRIVILEGES; ## Known Issues +### ClawManager Official Image Supports ARM64 + +- **Status**: `ghcr.io/yuan-lab-llm/clawmanager:latest` is published as a multi-platform image +- **Platforms**: `linux/amd64`, `linux/arm64` +- **Deployment impact**: ARM64 nodes automatically pull the matching main app image without a separate ARM-only tag + ### skill-scanner Official Image Has No ARM64 Support - **Problem**: `ghcr.io/yuan-lab-llm/skill-scanner:latest` only provides amd64 platform