Unify Dockerfiles, allow cross-compiling within Docker

This commit is contained in:
Caleb Xavier Berger 2021-01-20 06:18:49 -05:00
parent 8dbaa48705
commit f816563c2e
6 changed files with 104 additions and 51 deletions

36
build/docker/Dockerfile Normal file
View file

@ -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"]

View file

@ -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"]

View file

@ -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"]

View file

@ -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

59
build/docker/cross-helper.sh Executable file
View file

@ -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