From da99f47553afba1e20cae1bd6da5895e43779279 Mon Sep 17 00:00:00 2001 From: relnod Date: Tue, 1 Mar 2022 16:40:24 +0100 Subject: [PATCH] Build multiarch images for server (#821) Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Anbraten --- .woodpecker/docker.yml | 53 +++++++++++-------- Makefile | 32 +++++++++++ docker/Dockerfile.agent.alpine.multiarch | 2 +- docker/Dockerfile.agent.multiarch | 2 +- docker/Dockerfile.cli.alpine.multiarch | 2 +- docker/Dockerfile.cli.multiarch | 2 +- ...ine => Dockerfile.server.alpine.multiarch} | 9 ++-- ...ile.server => Dockerfile.server.multiarch} | 18 +++---- 8 files changed, 76 insertions(+), 44 deletions(-) rename docker/{Dockerfile.server.alpine => Dockerfile.server.alpine.multiarch} (66%) rename docker/{Dockerfile.server => Dockerfile.server.multiarch} (50%) diff --git a/.woodpecker/docker.yml b/.woodpecker/docker.yml index 74c0b7725e..f584cff3f4 100644 --- a/.woodpecker/docker.yml +++ b/.woodpecker/docker.yml @@ -3,6 +3,9 @@ depends_on: - web pipeline: + ############### + # S e r v e r # + ############### build-web: image: node:16-alpine commands: @@ -10,59 +13,61 @@ pipeline: - yarn install --frozen-lockfile - yarn build - ############### - # S e r v e r # - ############### - - # TODO: needed until https://github.com/woodpecker-ci/woodpecker/pull/635 - build-server: - image: golang:1.17 + cross-compile-server: + image: techknowlogick/xgo:go-1.17.x commands: - - make release-server + - apt update + - apt install -y tree + - make cross-compile-server + environment: + PLATFORMS: linux|arm/v7;linux|arm64/v8;linux|amd64;linux|ppc64le + TAGS: bindata sqlite sqlite_unlock_notify publish-server-dryrun: - image: plugins/docker + image: woodpeckerci/plugin-docker-buildx group: docker - secrets: [docker_username, docker_password] settings: dry_run: true repo: woodpeckerci/woodpecker-server - dockerfile: docker/Dockerfile.server - tag: next + dockerfile: docker/Dockerfile.server.multiarch + platforms: linux/arm/v7,linux/arm64/v8,linux/amd64,linux/ppc64le + tag: test when: event: pull_request publish-server-alpine-dryrun: - image: plugins/docker + image: woodpeckerci/plugin-docker-buildx group: docker - secrets: [ docker_username, docker_password ] settings: dry_run: true repo: woodpeckerci/woodpecker-server - dockerfile: docker/Dockerfile.server.alpine + dockerfile: docker/Dockerfile.server.alpine.multiarch + platforms: linux/arm/v7,linux/arm64/v8,linux/amd64,linux/ppc64le tag: next-alpine when: event: pull_request publish-next-server: - image: plugins/docker + image: woodpeckerci/plugin-docker-buildx group: docker secrets: [docker_username, docker_password] settings: repo: woodpeckerci/woodpecker-server - dockerfile: docker/Dockerfile.server + dockerfile: docker/Dockerfile.server.multiarch + platforms: linux/arm/v7,linux/arm64/v8,linux/amd64,linux/ppc64le tag: next when: branch: ${CI_REPO_DEFAULT_BRANCH} event: push publish-next-server-alpine: - image: plugins/docker + image: woodpeckerci/plugin-docker-buildx group: docker secrets: [ docker_username, docker_password ] settings: repo: woodpeckerci/woodpecker-server - dockerfile: docker/Dockerfile.server.alpine + dockerfile: docker/Dockerfile.server.alpine.multiarch + platforms: linux/arm/v7,linux/arm64/v8,linux/amd64,linux/ppc64le tag: next-alpine when: branch: ${CI_REPO_DEFAULT_BRANCH} @@ -94,11 +99,12 @@ pipeline: release-server: group: docker - image: plugins/docker + image: woodpeckerci/plugin-docker-buildx secrets: [docker_username, docker_password] settings: repo: woodpeckerci/woodpecker-server - dockerfile: docker/Dockerfile.server + dockerfile: docker/Dockerfile.server.multiarch + platforms: linux/arm/v7,linux/arm64/v8,linux/amd64,linux/ppc64le # remove 'latest' on older version branches to avoid accidental downgrade tag: [latest, "${CI_COMMIT_TAG}"] when: @@ -106,11 +112,12 @@ pipeline: release-server-alpine: group: docker - image: plugins/docker + image: woodpeckerci/plugin-docker-buildx secrets: [ docker_username, docker_password ] settings: repo: woodpeckerci/woodpecker-server - dockerfile: docker/Dockerfile.server.alpine + dockerfile: docker/Dockerfile.server.alpine.multiarch + platforms: linux/arm/v7,linux/arm64/v8,linux/amd64,linux/ppc64le # remove 'latest-alpine' on older version branches to avoid accidental downgrade tag: [latest-alpine, "${CI_COMMIT_TAG}-alpine"] when: diff --git a/Makefile b/Makefile index 136b589456..1a31f5d92e 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,13 @@ ifeq ($(BUILD_VERSION),next) endif LDFLAGS := -s -w -extldflags "-static" -X github.com/woodpecker-ci/woodpecker/version.Version=${BUILD_VERSION} +CGO_CFLAGS ?= + +HAS_GO = $(shell hash go > /dev/null 2>&1 && echo "GO" || echo "NOGO" ) +ifeq ($(HAS_GO), GO) + XGO_VERSION ?= go-1.17.x + CGO_CFLAGS ?= $(shell $(GO) env CGO_CFLAGS) +endif # If the first argument is "in_docker"... ifeq (in_docker,$(firstword $(MAKECMDGOALS))) @@ -117,6 +124,31 @@ build: build-agent build-server build-cli release-frontend: build-frontend +check-xgo: + @hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ + $(GO) install src.techknowlogick.com/xgo@latest; \ + fi + +cross-compile-server: + $(foreach platform,$(subst ;, ,$(PLATFORMS)),\ + TARGETOS=$(firstword $(subst |, ,$(platform))) \ + TARGETARCH_XGO=$(subst arm64/v8,arm64,$(subst arm/v7,arm-7,$(word 2,$(subst |, ,$(platform))))) \ + TARGETARCH_BUILDX=$(subst arm64/v8,arm64,$(subst arm/v7,arm,$(word 2,$(subst |, ,$(platform))))) \ + make release-server-xgo || exit 1; \ + ) + tree dist + +release-server-xgo: check-xgo + @echo "Building for:" + @echo "os:$(TARGETOS)" + @echo "arch orgi:$(TARGETARCH)" + @echo "arch (xgo):$(TARGETARCH_XGO)" + @echo "arch (buildx):$(TARGETARCH_BUILDX)" + + CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -dest ./dist/server/$(TARGETOS)-$(TARGETARCH_XGO) -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external $(LDFLAGS)' -targets '$(TARGETOS)/$(TARGETARCH_XGO)' -out woodpecker-server -pkg cmd/server . + mkdir -p ./dist/server/$(TARGETOS)/$(TARGETARCH_BUILDX) + mv /build/woodpecker-server-$(TARGETOS)-$(TARGETARCH_XGO) ./dist/server/$(TARGETOS)/$(TARGETARCH_BUILDX)/woodpecker-server + release-server: # compile GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -ldflags '${LDFLAGS}' -o dist/server/linux_amd64/woodpecker-server github.com/woodpecker-ci/woodpecker/cmd/server diff --git a/docker/Dockerfile.agent.alpine.multiarch b/docker/Dockerfile.agent.alpine.multiarch index 436c78efe0..90d3c9ddde 100644 --- a/docker/Dockerfile.agent.alpine.multiarch +++ b/docker/Dockerfile.agent.alpine.multiarch @@ -12,7 +12,7 @@ RUN apk add -U --no-cache ca-certificates ENV GODEBUG=netdns=go EXPOSE 3000 -COPY --from=build src/dist/woodpecker-agent /bin/ +COPY --from=build /src/dist/woodpecker-agent /bin/ HEALTHCHECK CMD ["/bin/woodpecker-agent", "ping"] ENTRYPOINT ["/bin/woodpecker-agent"] diff --git a/docker/Dockerfile.agent.multiarch b/docker/Dockerfile.agent.multiarch index 994db0c3d8..00b0576f6a 100644 --- a/docker/Dockerfile.agent.multiarch +++ b/docker/Dockerfile.agent.multiarch @@ -14,7 +14,7 @@ EXPOSE 3000 # copy certs from golang:1.16 image COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt # copy agent binary -COPY --from=build src/dist/woodpecker-agent /bin/ +COPY --from=build /src/dist/woodpecker-agent /bin/ HEALTHCHECK CMD ["/bin/woodpecker-agent", "ping"] ENTRYPOINT ["/bin/woodpecker-agent"] diff --git a/docker/Dockerfile.cli.alpine.multiarch b/docker/Dockerfile.cli.alpine.multiarch index 4270378585..97994aeb43 100644 --- a/docker/Dockerfile.cli.alpine.multiarch +++ b/docker/Dockerfile.cli.alpine.multiarch @@ -11,7 +11,7 @@ FROM alpine:3.14 RUN apk add -U --no-cache ca-certificates ENV GODEBUG=netdns=go -COPY --from=build src/dist/woodpecker-cli /bin/ +COPY --from=build /src/dist/woodpecker-cli /bin/ HEALTHCHECK CMD ["/bin/woodpecker-cli", "ping"] ENTRYPOINT ["/bin/woodpecker-cli"] diff --git a/docker/Dockerfile.cli.multiarch b/docker/Dockerfile.cli.multiarch index af2dcad11b..35bbba0579 100644 --- a/docker/Dockerfile.cli.multiarch +++ b/docker/Dockerfile.cli.multiarch @@ -13,7 +13,7 @@ ENV GODEBUG=netdns=go # copy certs from golang:1.16 image COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt # copy cli binary -COPY --from=build src/dist/woodpecker-cli /bin/ +COPY --from=build /src/dist/woodpecker-cli /bin/ HEALTHCHECK CMD ["/bin/woodpecker-cli", "ping"] ENTRYPOINT ["/bin/woodpecker-cli"] diff --git a/docker/Dockerfile.server.alpine b/docker/Dockerfile.server.alpine.multiarch similarity index 66% rename from docker/Dockerfile.server.alpine rename to docker/Dockerfile.server.alpine.multiarch index cb054e2a4e..9f1a3fe4c6 100644 --- a/docker/Dockerfile.server.alpine +++ b/docker/Dockerfile.server.alpine.multiarch @@ -1,15 +1,12 @@ -# docker build --rm -f docker/Dockerfile.server.alpine -t woodpeckerci/woodpecker-server . - FROM alpine:3.14 +ARG TARGETOS TARGETARCH RUN apk add -U --no-cache ca-certificates - -EXPOSE 8000 9000 80 443 - ENV GODEBUG=netdns=go ENV WOODPECKER_DATABASE_DATASOURCE=/var/lib/woodpecker/woodpecker.sqlite ENV WOODPECKER_DATABASE_DRIVER=sqlite3 ENV XDG_CACHE_HOME=/var/lib/woodpecker +EXPOSE 8000 9000 80 443 -ADD dist/server/linux_amd64/woodpecker-server /bin/ +COPY dist/server/${TARGETOS}/${TARGETARCH}/woodpecker-server /bin/ ENTRYPOINT ["/bin/woodpecker-server"] diff --git a/docker/Dockerfile.server b/docker/Dockerfile.server.multiarch similarity index 50% rename from docker/Dockerfile.server rename to docker/Dockerfile.server.multiarch index 0e6bd017c7..b5e8112b85 100644 --- a/docker/Dockerfile.server +++ b/docker/Dockerfile.server.multiarch @@ -1,20 +1,16 @@ -# docker build --rm -f docker/Dockerfile.server -t woodpeckerci/woodpecker-server . - -# use golang image to copy ssl certs later -FROM golang:1.16 +FROM golang:1.16 AS certs FROM scratch - -# copy certs from golang:1.16 image -COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt - -EXPOSE 8000 9000 80 443 - +ARG TARGETOS TARGETARCH ENV GODEBUG=netdns=go ENV WOODPECKER_DATABASE_DATASOURCE=/var/lib/woodpecker/woodpecker.sqlite ENV WOODPECKER_DATABASE_DRIVER=sqlite3 ENV XDG_CACHE_HOME=/var/lib/woodpecker +EXPOSE 8000 9000 80 443 -ADD dist/server/linux_amd64/woodpecker-server /bin/ +# copy certs from golang:1.16 image +COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +# copy server binary +COPY dist/server/${TARGETOS}/${TARGETARCH}/woodpecker-server /bin/ ENTRYPOINT ["/bin/woodpecker-server"]