From cd17c2ebe72d21fb677311e822fc3f2131c45215 Mon Sep 17 00:00:00 2001 From: zijiren <84728412+zijiren233@users.noreply.github.com> Date: Tue, 27 Jan 2026 15:52:56 +0800 Subject: [PATCH] feat(ci): service build on docker and arm runner (#6608) feat(ci): service build on docker and arm runner (#6596) * feat: service build on docker and arm runner * fix: build context * fix: go mod downlaod cache * fix: go build main pachage * fix: hubble build main package * fix: remote jsoniter tag * fix: configure ReadHeaderTimeout for minio http server (#129) --------- Co-authored-by: xzy --- .github/workflows/service-build.yml | 176 ++++++++++++++++++---------- service/account/Dockerfile | 35 +++++- service/database/Dockerfile | 37 +++++- service/devbox/Dockerfile | 35 +++++- service/exceptionmonitor/Dockerfile | 33 +++++- service/hubble/Dockerfile | 37 +++++- service/launchpad/Dockerfile | 37 +++++- service/minio/Dockerfile | 37 +++++- service/minio/server/server.go | 6 +- service/pay/Dockerfile | 34 +++++- service/vlogs/Dockerfile | 37 +++++- 11 files changed, 407 insertions(+), 97 deletions(-) diff --git a/.github/workflows/service-build.yml b/.github/workflows/service-build.yml index c510de580..59c3879d0 100644 --- a/.github/workflows/service-build.yml +++ b/.github/workflows/service-build.yml @@ -70,7 +70,13 @@ jobs: args: --color=always --config=${{ github.workspace }}/.golangci.yml image-build: - runs-on: ubuntu-24.04 + strategy: + matrix: + include: + - arch: amd64 + - arch: arm64 + runs-on: ubuntu-24.04-arm + runs-on: ${{ matrix.runs-on || 'ubuntu-24.04' }} permissions: contents: read packages: write @@ -80,80 +86,122 @@ jobs: with: fetch-depth: 0 - - name: Setup Golang with cache - uses: magnetikonline/action-golang-cache@v5 - with: - go-version: ${{ env.GO_VERSION }} - - - name: Install Dependencies - run: sudo apt update && sudo apt install -y libgpgme-dev libbtrfs-dev libdevmapper-dev - - - name: Build ${{ inputs.module }} amd64 - working-directory: service/${{ inputs.module }} - env: - MODULE: ${{ inputs.module }} - run: | - GOARCH=amd64 make build - mv bin/manager bin/service-${MODULE}-amd64 - chmod +x bin/service-${MODULE}-amd64 - file bin/service-${MODULE}-amd64 - file bin/service-${MODULE}-amd64 | grep -q 'x86-64' - if [ $? -ne 0 ]; then - echo "amd64 platform build failed" - exit 1 - fi - - - name: Build ${{ inputs.module }} arm64 - working-directory: service/${{ inputs.module }} - env: - MODULE: ${{ inputs.module }} - run: | - GOARCH=arm64 make build - mv bin/manager bin/service-${MODULE}-arm64 - chmod +x bin/service-${MODULE}-arm64 - file bin/service-${MODULE}-arm64 - file bin/service-${MODULE}-arm64 | grep -q 'aarch64' - if [ $? -ne 0 ]; then - echo "arm64 platform build failed" - exit 1 - fi - - name: Set image repo - id: set-outputs + id: set_repo env: - REPO_OWNER: ${{ github.repository_owner }} MODULE: ${{ inputs.module }} + REPOSITORY_OWNER: ${{ github.repository_owner }} run: | - echo "GHCR_REPO=ghcr.io/${REPO_OWNER}/sealos-${MODULE}-service" >> $GITHUB_ENV - echo "image-name=ghcr.io/${REPO_OWNER}/sealos-${MODULE}-service" >> $GITHUB_OUTPUT + echo "GHCR_REPO=ghcr.io/${REPOSITORY_OWNER}/sealos-${MODULE}-service" >> $GITHUB_ENV if [[ -n "${{ env.ALIYUN_REPO_PREFIX }}" ]]; then echo "ALIYUN_REPO=${{ env.ALIYUN_REPO_PREFIX }}/sealos-${MODULE}-service" >> $GITHUB_ENV fi - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ env.GHCR_REPO }} + ${{ env.ALIYUN_REPO }} + labels: | + org.opencontainers.image.source=https://github.com/${{ github.repository }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - with: - driver-opts: network=host - - name: Login to Docker Hub - uses: docker/login-action@v3 + - name: Login to Github Container Hub if: ${{ inputs.push_image }} + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GHCR_TOKEN || secrets.GITHUB_TOKEN }} - name: Login to Aliyun Registry - uses: docker/login-action@v3 if: ${{ inputs.push_image && env.ALIYUN_REGISTRY }} + uses: docker/login-action@v3 with: registry: ${{ env.ALIYUN_REGISTRY }} username: ${{ secrets.ALIYUN_USERNAME }} password: ${{ secrets.ALIYUN_PASSWORD }} + - name: Build + id: build + uses: docker/build-push-action@v6 + with: + context: . + file: ./service/${{ inputs.module }}/Dockerfile + platforms: linux/${{ matrix.arch }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,"name=${{ env.GHCR_REPO }}${{ env.ALIYUN_REPO && format(',{0}', env.ALIYUN_REPO) || '' }}",name-canonical=true,push-by-digest=${{ inputs.push_image }},push=${{ inputs.push_image }} + + - name: Export digest + env: + TEMP_DIR: ${{ runner.temp }} + DIGEST: ${{ steps.build.outputs.digest }} + run: | + mkdir -p "${TEMP_DIR}/digests" + touch "${TEMP_DIR}/digests/${DIGEST#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ inputs.module }}-${{ matrix.arch }} + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 + + image-release: + name: Push Docker Images + needs: image-build + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: write + if: ${{ inputs.push_image }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Login to Github Container Hub + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GHCR_TOKEN || secrets.GITHUB_TOKEN }} + + - name: Login to Aliyun Registry + if: ${{ env.ALIYUN_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.ALIYUN_REGISTRY }} + username: ${{ secrets.ALIYUN_USERNAME }} + password: ${{ secrets.ALIYUN_PASSWORD }} + + - name: Set image repo + id: set_repo + env: + MODULE: ${{ inputs.module }} + REPOSITORY_OWNER: ${{ github.repository_owner }} + run: | + echo "GHCR_REPO=ghcr.io/${REPOSITORY_OWNER}/sealos-${MODULE}-service" >> $GITHUB_ENV + if [[ -n "${{ env.ALIYUN_REPO_PREFIX }}" ]]; then + echo "ALIYUN_REPO=${{ env.ALIYUN_REPO_PREFIX }}/sealos-${MODULE}-service" >> $GITHUB_ENV + fi + + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: ${{ runner.temp }}/digests + pattern: digests-${{ inputs.module }}-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Docker meta id: meta uses: docker/metadata-action@v5 @@ -167,23 +215,29 @@ jobs: type=ref,event=branch type=ref,event=tag type=sha + labels: | + org.opencontainers.image.source=https://github.com/${{ github.repository }} env: DOCKER_METADATA_SHORT_SHA_LENGTH: 9 - - name: build (and publish) ${{ inputs.module }} main image - uses: docker/build-push-action@v6 - with: - context: ./service/${{ inputs.module }} - file: ./service/${{ inputs.module }}/Dockerfile - # Push if it's a push event or if push_image is true - push: ${{ inputs.push_image }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64,linux/arm64 + - name: Create manifest list and push + working-directory: ${{ runner.temp }}/digests + env: + GHCR_REPO: ${{ env.GHCR_REPO }} + IMAGE_SOURCE: https://github.com/${{ github.repository }} + run: | + for TAG in $DOCKER_METADATA_OUTPUT_TAGS; do + docker buildx imagetools create \ + --annotation "index:org.opencontainers.image.source=${IMAGE_SOURCE}" \ + -t $TAG \ + $(printf "${GHCR_REPO}@sha256:%s " *) + sleep 5 + done cluster-image-build: + needs: + - image-release if: ${{ inputs.push_image }} - needs: [image-build] runs-on: ubuntu-24.04 permissions: contents: read diff --git a/service/account/Dockerfile b/service/account/Dockerfile index 64635ebe5..d97143379 100644 --- a/service/account/Dockerfile +++ b/service/account/Dockerfile @@ -1,7 +1,36 @@ +# Build stage +FROM golang:1.25-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache \ + git \ + ca-certificates \ + && update-ca-certificates + +WORKDIR /workspace + +ENV CGO_ENABLED=0 + +COPY . . + +RUN cd service/account && go mod download + +RUN cd service/account && \ + go build -tags=jsoniter \ + -trimpath \ + -ldflags "-s -w" \ + -o /manager \ + . + +# Runtime stage FROM gcr.io/distroless/static:nonroot -ARG TARGETARCH -COPY bin/service-account-$TARGETARCH /manager -EXPOSE 9090 + +# Copy the binary from builder +COPY --from=builder /manager /manager + +# Use non-root user USER 65532:65532 +EXPOSE 9090 + ENTRYPOINT ["/manager"] \ No newline at end of file diff --git a/service/database/Dockerfile b/service/database/Dockerfile index 549a7c848..c0ea25df1 100644 --- a/service/database/Dockerfile +++ b/service/database/Dockerfile @@ -1,9 +1,36 @@ -# FROM scratch +# Build stage +FROM golang:1.25-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache \ + git \ + ca-certificates \ + && update-ca-certificates + +WORKDIR /workspace + +ENV CGO_ENABLED=0 + +COPY . . + +RUN cd service/database && go mod download + +RUN cd service/database && \ + go build \ + -trimpath \ + -ldflags "-s -w" \ + -o /manager \ + . + +# Runtime stage FROM gcr.io/distroless/static:nonroot -# FROM gengweifeng/gcr-io-distroless-static-nonroot -ARG TARGETARCH -COPY bin/service-database-$TARGETARCH /manager -EXPOSE 9090 + +# Copy the binary from builder +COPY --from=builder /manager /manager + +# Use non-root user USER 65532:65532 +EXPOSE 9090 + ENTRYPOINT ["/manager"] diff --git a/service/devbox/Dockerfile b/service/devbox/Dockerfile index 22711bf79..117605572 100644 --- a/service/devbox/Dockerfile +++ b/service/devbox/Dockerfile @@ -1,7 +1,36 @@ +# Build stage +FROM golang:1.25-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache \ + git \ + ca-certificates \ + && update-ca-certificates + +WORKDIR /workspace + +ENV CGO_ENABLED=0 + +COPY . . + +RUN cd service/devbox && go mod download + +RUN cd service/devbox && \ + go build -tags=jsoniter \ + -trimpath \ + -ldflags "-s -w" \ + -o /manager \ + . + +# Runtime stage FROM gcr.io/distroless/static:nonroot -ARG TARGETARCH -COPY bin/service-devbox-$TARGETARCH /manager -EXPOSE 8092 + +# Copy the binary from builder +COPY --from=builder /manager /manager + +# Use non-root user USER 65532:65532 +EXPOSE 8092 + ENTRYPOINT ["/manager"] \ No newline at end of file diff --git a/service/exceptionmonitor/Dockerfile b/service/exceptionmonitor/Dockerfile index f3643dd05..85b3f914a 100644 --- a/service/exceptionmonitor/Dockerfile +++ b/service/exceptionmonitor/Dockerfile @@ -1,5 +1,34 @@ +# Build stage +FROM golang:1.25-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache \ + git \ + ca-certificates \ + && update-ca-certificates + +WORKDIR /workspace + +ENV CGO_ENABLED=0 + +COPY . . + +RUN cd service/exceptionmonitor && go mod download + +RUN cd service/exceptionmonitor && \ + go build \ + -trimpath \ + -ldflags "-s -w" \ + -o /manager \ + . + +# Runtime stage FROM gcr.io/distroless/static:nonroot -ARG TARGETARCH -COPY bin/service-exceptionmonitor-$TARGETARCH /manager + +# Copy the binary from builder +COPY --from=builder /manager /manager + +# Use non-root user USER 65532:65532 + ENTRYPOINT ["/manager"] \ No newline at end of file diff --git a/service/hubble/Dockerfile b/service/hubble/Dockerfile index cffe71895..9512e6ab3 100644 --- a/service/hubble/Dockerfile +++ b/service/hubble/Dockerfile @@ -1,7 +1,36 @@ +# Build stage +FROM golang:1.25-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache \ + git \ + ca-certificates \ + && update-ca-certificates + +WORKDIR /workspace + +ENV CGO_ENABLED=0 + +COPY . . + +RUN cd service/hubble && go mod download + +RUN cd service/hubble && \ + go build \ + -trimpath \ + -ldflags "-s -w" \ + -o /manager \ + ./cmd + +# Runtime stage FROM gcr.io/distroless/static:nonroot -ARG TARGETARCH -COPY bin/service-hubble-$TARGETARCH /manager -EXPOSE 8428 + +# Copy the binary from builder +COPY --from=builder /manager /manager + +# Use non-root user USER 65532:65532 -ENTRYPOINT [ "/manager", "config/config.yml" ] \ No newline at end of file +EXPOSE 8428 + +ENTRYPOINT ["/manager", "config/config.yml"] \ No newline at end of file diff --git a/service/launchpad/Dockerfile b/service/launchpad/Dockerfile index 1352f47e5..0140a1ae9 100644 --- a/service/launchpad/Dockerfile +++ b/service/launchpad/Dockerfile @@ -1,9 +1,36 @@ -# FROM scratch +# Build stage +FROM golang:1.25-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache \ + git \ + ca-certificates \ + && update-ca-certificates + +WORKDIR /workspace + +ENV CGO_ENABLED=0 + +COPY . . + +RUN cd service/launchpad && go mod download + +RUN cd service/launchpad && \ + go build \ + -trimpath \ + -ldflags "-s -w" \ + -o /manager \ + . + +# Runtime stage FROM gcr.io/distroless/static:nonroot -# FROM gengweifeng/gcr-io-distroless-static-nonroot -ARG TARGETARCH -COPY bin/service-launchpad-$TARGETARCH /manager -EXPOSE 9090 + +# Copy the binary from builder +COPY --from=builder /manager /manager + +# Use non-root user USER 65532:65532 +EXPOSE 9090 + ENTRYPOINT ["/manager"] diff --git a/service/minio/Dockerfile b/service/minio/Dockerfile index 565b0de41..2bbc39e7d 100644 --- a/service/minio/Dockerfile +++ b/service/minio/Dockerfile @@ -1,9 +1,36 @@ -# FROM scratch +# Build stage +FROM golang:1.25-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache \ + git \ + ca-certificates \ + && update-ca-certificates + +WORKDIR /workspace + +ENV CGO_ENABLED=0 + +COPY . . + +RUN cd service/minio && go mod download + +RUN cd service/minio && \ + go build \ + -trimpath \ + -ldflags "-s -w" \ + -o /manager \ + . + +# Runtime stage FROM gcr.io/distroless/static:nonroot -# FROM gengweifeng/gcr-io-distroless-static-nonroot -ARG TARGETARCH -COPY bin/service-minio-$TARGETARCH /manager -EXPOSE 9090 + +# Copy the binary from builder +COPY --from=builder /manager /manager + +# Use non-root user USER 65532:65532 +EXPOSE 9090 + ENTRYPOINT ["/manager"] \ No newline at end of file diff --git a/service/minio/server/server.go b/service/minio/server/server.go index 4f5b9b410..8b2908ed4 100644 --- a/service/minio/server/server.go +++ b/service/minio/server/server.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "net/http" + "time" "github.com/labring/sealos/service/pkg/server" ) @@ -20,8 +21,9 @@ func (rs *MinioServer) Serve(c *server.Config) { } hs := &http.Server{ - Addr: c.Server.ListenAddress, - Handler: ps, + Addr: c.Server.ListenAddress, + Handler: ps, + ReadHeaderTimeout: 10 * time.Second, } listener, err := net.Listen("tcp", c.Server.ListenAddress) diff --git a/service/pay/Dockerfile b/service/pay/Dockerfile index 934627a34..c75b0a75d 100644 --- a/service/pay/Dockerfile +++ b/service/pay/Dockerfile @@ -1,8 +1,36 @@ +# Build stage +FROM golang:1.25-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache \ + git \ + ca-certificates \ + && update-ca-certificates + +WORKDIR /workspace + +ENV CGO_ENABLED=0 + +COPY . . + +RUN cd service/pay && go mod download + +RUN cd service/pay && \ + go build \ + -trimpath \ + -ldflags "-s -w" \ + -o /manager \ + . + +# Runtime stage FROM gcr.io/distroless/static:nonroot -ARG TARGETARCH -COPY bin/service-pay-$TARGETARCH /manager -EXPOSE 2303 +# Copy the binary from builder +COPY --from=builder /manager /manager + +# Use non-root user USER 65532:65532 +EXPOSE 2303 + ENTRYPOINT ["/manager"] \ No newline at end of file diff --git a/service/vlogs/Dockerfile b/service/vlogs/Dockerfile index f9fee8e8f..c70b8d4ed 100644 --- a/service/vlogs/Dockerfile +++ b/service/vlogs/Dockerfile @@ -1,7 +1,36 @@ +# Build stage +FROM golang:1.25-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache \ + git \ + ca-certificates \ + && update-ca-certificates + +WORKDIR /workspace + +ENV CGO_ENABLED=0 + +COPY . . + +RUN cd service/vlogs && go mod download + +RUN cd service/vlogs && \ + go build \ + -trimpath \ + -ldflags "-s -w" \ + -o /manager \ + . + +# Runtime stage FROM gcr.io/distroless/static:nonroot -ARG TARGETARCH -COPY bin/service-vlogs-$TARGETARCH /manager -EXPOSE 8428 + +# Copy the binary from builder +COPY --from=builder /manager /manager + +# Use non-root user USER 65532:65532 -ENTRYPOINT [ "/manager", "config/config.yml" ] \ No newline at end of file +EXPOSE 8428 + +ENTRYPOINT ["/manager", "config/config.yml"] \ No newline at end of file