From f816563c2e0770ea933f1cf5ad33e92cbfa84628 Mon Sep 17 00:00:00 2001 From: Caleb Xavier Berger Date: Wed, 20 Jan 2021 06:18:49 -0500 Subject: [PATCH] Unify Dockerfiles, allow cross-compiling within Docker --- .dockerignore | 2 +- build/docker/Dockerfile | 36 +++++++++++++++++++ build/docker/Dockerfile.monolith | 22 ------------ build/docker/Dockerfile.polylith | 22 ------------ build/docker/README.md | 14 ++++---- build/docker/cross-helper.sh | 59 ++++++++++++++++++++++++++++++++ 6 files changed, 104 insertions(+), 51 deletions(-) create mode 100644 build/docker/Dockerfile delete mode 100644 build/docker/Dockerfile.monolith delete mode 100644 build/docker/Dockerfile.polylith create mode 100755 build/docker/cross-helper.sh diff --git a/.dockerignore b/.dockerignore index 76547e9ee..2d437e932 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,3 @@ bin *.wasm -.git \ No newline at end of file +.git diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile new file mode 100644 index 000000000..cf0f872a2 --- /dev/null +++ b/build/docker/Dockerfile @@ -0,0 +1,36 @@ +# The binary to build the image around (monolith or polylith). +ARG DENDRITE_BINARY + +FROM --platform=$BUILDPLATFORM docker.io/golang:alpine AS base +ARG TARGETARCH +ARG DENDRITE_BINARY +ENV GOARCH=$TARGETARCH +ENV CGO_ENABLED=1 +# The host triple of the *builder container.* Will end in musl because Alpine. E.g. aarch64-linux-musl. +# Only relevant when cross-compiling. +ARG HOST_TRIPLE="x86_64-linux-musl" + +# Todo: Do we *really* need rsync? +RUN apk --update --no-cache add bash build-base curl rsync + +WORKDIR /build +COPY . /build + +RUN bash ./build/docker/cross-helper.sh dl-compiler + +RUN mkdir -p bin +RUN CC=$(./build/docker/cross-helper.sh cc) go build -trimpath -o bin/ ./cmd/$DENDRITE_BINARY +RUN CC=$(./build/docker/cross-helper.sh cc) go build -trimpath -o bin/ ./cmd/goose +RUN CC=$(./build/docker/cross-helper.sh cc) go build -trimpath -o bin/ ./cmd/create-account +RUN CC=$(./build/docker/cross-helper.sh cc) go build -trimpath -o bin/ ./cmd/generate-keys + +FROM alpine:latest +ARG DENDRITE_BINARY +ENV DENDRITE_BINARY=$DENDRITE_BINARY + +COPY --from=base /build/bin/* /usr/bin/ + +VOLUME /etc/dendrite +WORKDIR /etc/dendrite + +ENTRYPOINT ["/usr/bin/$DENDRITE_BINARY"] diff --git a/build/docker/Dockerfile.monolith b/build/docker/Dockerfile.monolith deleted file mode 100644 index eb099c4cc..000000000 --- a/build/docker/Dockerfile.monolith +++ /dev/null @@ -1,22 +0,0 @@ -FROM docker.io/golang:1.15-alpine AS base - -RUN apk --update --no-cache add bash build-base - -WORKDIR /build - -COPY . /build - -RUN mkdir -p bin -RUN go build -trimpath -o bin/ ./cmd/dendrite-monolith-server -RUN go build -trimpath -o bin/ ./cmd/goose -RUN go build -trimpath -o bin/ ./cmd/create-account -RUN go build -trimpath -o bin/ ./cmd/generate-keys - -FROM alpine:latest - -COPY --from=base /build/bin/* /usr/bin - -VOLUME /etc/dendrite -WORKDIR /etc/dendrite - -ENTRYPOINT ["/usr/bin/dendrite-monolith-server"] \ No newline at end of file diff --git a/build/docker/Dockerfile.polylith b/build/docker/Dockerfile.polylith deleted file mode 100644 index 1a7ba193e..000000000 --- a/build/docker/Dockerfile.polylith +++ /dev/null @@ -1,22 +0,0 @@ -FROM docker.io/golang:1.15-alpine AS base - -RUN apk --update --no-cache add bash build-base - -WORKDIR /build - -COPY . /build - -RUN mkdir -p bin -RUN go build -trimpath -o bin/ ./cmd/dendrite-polylith-multi -RUN go build -trimpath -o bin/ ./cmd/goose -RUN go build -trimpath -o bin/ ./cmd/create-account -RUN go build -trimpath -o bin/ ./cmd/generate-keys - -FROM alpine:latest - -COPY --from=base /build/bin/* /usr/bin - -VOLUME /etc/dendrite -WORKDIR /etc/dendrite - -ENTRYPOINT ["/usr/bin/dendrite-polylith-multi"] \ No newline at end of file diff --git a/build/docker/README.md b/build/docker/README.md index 818f92d03..06031afeb 100644 --- a/build/docker/README.md +++ b/build/docker/README.md @@ -7,13 +7,15 @@ They can be found on Docker Hub: - [matrixdotorg/dendrite-monolith](https://hub.docker.com/r/matrixdotorg/dendrite-monolith) for monolith deployments - [matrixdotorg/dendrite-polylith](https://hub.docker.com/r/matrixdotorg/dendrite-polylith) for polylith deployments -## Dockerfiles +## Building the image -The `Dockerfile` builds the base image which contains all of the Dendrite -components. The `Dockerfile.component` file takes the given component, as -specified with `--buildarg component=` from the base image and produce -smaller component-specific images, which are substantially smaller and do -not contain the Go toolchain etc. +The `Dockerfile` can build both monolith and polylith images for Dendrite. +To choose which is selected, set `--build-arg DENDRITE_BINARY=$binary`, +where `$binary` is `dendrite-monolith-server` or `dendrite-polylith-multi` +for monolith or polylith respectively. + +Note that you **must** use BuildKit to build the images. You can enable +it for the build with `DOCKER_BUILDKIT=1 docker build [...]` ## Compose files diff --git a/build/docker/cross-helper.sh b/build/docker/cross-helper.sh new file mode 100755 index 000000000..59a5f3957 --- /dev/null +++ b/build/docker/cross-helper.sh @@ -0,0 +1,59 @@ +#!/bin/bash +set -eu + +# Utility script for getting and using cross-compilation toolchains in Docker. +# You really shouldn't run this outside of a container, though there's no reason you can't. + +# $1 is used for arch +function install_musl() { + rm musl.tgz + cd ${1}-cross + rm -f $(find . -name "ld-musl-*.so.1") + rm usr + # error supression! + rsync --ignore-errors -rLaq . / || true + cd .. + rm -rf ${1}-cross +} + +function get_triple() { + case "${1}" in + "arm64") + echo "aarch64-linux-musl" + ;; + "arm") + echo "arm-linux-musleabi" + ;; + "amd64") + echo "x86_64-linux-musl" + ;; + *) + exit 1 + ;; + esac +} + +arch=$(go env GOARCH) + +case "${1}" in +"dl-compiler") + if [[ "${arch}" == "$(go env GOHOSTARCH)" ]]; then + echo "not cross-compiling, nothing to do" + exit 0 + fi + MUSLCC_BASE="https://more.musl.cc/${HOST_TRIPLE}" + target="$(get_triple ${arch})" + curl "${MUSLCC_BASE}/${target}-cross.tgz" -o musl.tgz + tar xzf musl.tgz + install_musl ${target} + ;; +"cc") + if [[ ${arch} == "$(go env GOHOSTARCH)" ]]; then + echo "gcc" + else + echo "$(get_triple $(go env GOARCH))-gcc" + fi + ;; +*) + exit 1 +esac