From f8562407923e1c1d73ada0426a1894d841940971 Mon Sep 17 00:00:00 2001 From: Csongor Kiss Date: Wed, 6 Jul 2022 19:27:49 +0100 Subject: [PATCH] node: Prepare development binary release (#1332) * node: Shrink final docker image size * Tiltfile: guardiand should run the build stage * node: allow building without -race * node: Support development builds A development build must use the --unsafeDevMode flag. * CI: build docker image Co-authored-by: Csongor Kiss --- .github/workflows/guardiand-docker.yml | 45 ++++++++++++++++++++++++++ Tiltfile | 1 + node/Dockerfile | 22 +++++++++++-- node/cmd/guardiand/node.go | 13 +++++++- 4 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/guardiand-docker.yml diff --git a/.github/workflows/guardiand-docker.yml b/.github/workflows/guardiand-docker.yml new file mode 100644 index 000000000..b8abe3fc6 --- /dev/null +++ b/.github/workflows/guardiand-docker.yml @@ -0,0 +1,45 @@ +name: Publish guardiand development docker image + +on: + workflow_dispatch: + release: + types: [published] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: certusone/guardiand + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Log in to the Container registry + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - run: DOCKER_BUILDKIT=1 docker build --target go-export -f Dockerfile.proto -o type=local,dest=node . + + - name: Build and push Docker image + uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + with: + context: ./node + push: true + tags: ${{ steps.meta.outputs.tags }} + target: export + build-args: GO_BUILD_ARGS= diff --git a/Tiltfile b/Tiltfile index d0afdb6a4..fa8f61802 100644 --- a/Tiltfile +++ b/Tiltfile @@ -141,6 +141,7 @@ docker_build( ref = "guardiand-image", context = "node", dockerfile = "node/Dockerfile", + target = "build", ) def command_with_dlv(argv): diff --git a/node/Dockerfile b/node/Dockerfile index c8bbfb4ba..fc2781300 100644 --- a/node/Dockerfile +++ b/node/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker.io/docker/dockerfile:1.3@sha256:42399d4635eddd7a9b8a24be879d2f9a930d0ed040a61324cfdf59ef1357b3b2 -FROM docker.io/golang:1.17.5@sha256:90d1ab81f3d157ca649a9ff8d251691b810d95ea6023a03cdca139df58bca599 +FROM docker.io/golang:1.17.5@sha256:90d1ab81f3d157ca649a9ff8d251691b810d95ea6023a03cdca139df58bca599 AS build # Support additional root CAs COPY go.mod cert.pem* /certs/ @@ -17,8 +17,24 @@ RUN --mount=type=cache,target=/root/.cache --mount=type=cache,target=/go \ ADD . . +ARG GO_BUILD_ARGS=-race + RUN --mount=type=cache,target=/root/.cache --mount=type=cache,target=/go \ - go build -race -gcflags="all=-N -l" --ldflags '-extldflags "-Wl,--allow-multiple-definition"' -mod=readonly -o /guardiand github.com/certusone/wormhole/node && \ + go build ${GO_BUILD_ARGS} -gcflags="all=-N -l" --ldflags '-extldflags "-Wl,--allow-multiple-definition" -X "github.com/certusone/wormhole/node/cmd/guardiand.Build=dev"' -mod=readonly -o /guardiand github.com/certusone/wormhole/node && \ cp /go/pkg/mod/github.com/!cosm!wasm/wasmvm@v0.16.2/api/libwasmvm.so /usr/lib/ -ENTRYPOINT /guardiand +# Only export the final binary (+ shared objects). This reduces the image size +# from ~1GB to ~150MB. +FROM scratch as export + +# guardiand can't (easily) be statically linked due to the C dependencies, so we +# have to copy all the dynamic libraries +COPY --from=build /bin/* /bin/ +COPY --from=build /lib/* /lib/ +COPY --from=build /lib64/* /lib64/ +COPY --from=build /usr/lib/libwasmvm.so /usr/lib/ + +# finally copy the guardian executable +COPY --from=build /guardiand . + +ENTRYPOINT ["/guardiand"] diff --git a/node/cmd/guardiand/node.go b/node/cmd/guardiand/node.go index 5c31adfd5..7e6fd0147 100644 --- a/node/cmd/guardiand/node.go +++ b/node/cmd/guardiand/node.go @@ -281,7 +281,7 @@ const devwarning = ` +++++++++++++++++++++++++++++++++++++++++++++++++++ | NODE IS RUNNING IN INSECURE DEVELOPMENT MODE | | | - | Do not use -unsafeDevMode in prod. | + | Do not use --unsafeDevMode in prod. | +++++++++++++++++++++++++++++++++++++++++++++++++++ ` @@ -293,7 +293,18 @@ var NodeCmd = &cobra.Command{ Run: runNode, } +// This variable may be overridden by the -X linker flag to "dev" in which case +// we enforce the --unsafeDevMode flag. Only development binaries/docker images +// are distributed. Production binaries are required to be built from source by +// guardians to reduce risk from a compromised builder. +var Build = "prod" + func runNode(cmd *cobra.Command, args []string) { + if Build == "dev" && !*unsafeDevMode { + fmt.Println("This is a development build. --unsafeDevMode must be enabled.") + os.Exit(1) + } + if *unsafeDevMode { fmt.Print(devwarning) }