summaryrefslogtreecommitdiff
path: root/Dockerfile
diff options
context:
space:
mode:
authorJonas Zohren <gitlab-jfowl-0ux98@sh14.de>2021-11-21 17:34:08 +0000
committerTimo Kösters <timo@koesters.xyz>2021-11-21 17:34:08 +0000
commit2fff720df38c83673269fa597361c5631e991c9a (patch)
tree62ad8f3e7aefce0347fe59d6c9db6d16b30afd82 /Dockerfile
parent24a835647c0d9d5a678a495c2edf4ed7b7a39bdf (diff)
downloadconduit-2fff720df38c83673269fa597361c5631e991c9a.zip
CI: New Multiarch builds and Docker images + cargo clippy/test output now integrated into GitLab
Diffstat (limited to 'Dockerfile')
-rw-r--r--Dockerfile135
1 files changed, 60 insertions, 75 deletions
diff --git a/Dockerfile b/Dockerfile
index f4b176f..d137353 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,75 +1,66 @@
-# Using multistage build:
-# https://docs.docker.com/develop/develop-images/multistage-build/
-# https://whitfin.io/speeding-up-rust-docker-builds/
+# syntax=docker/dockerfile:1
+FROM docker.io/rust:1.53-alpine AS builder
+WORKDIR /usr/src/conduit
+# Install required packages to build Conduit and it's dependencies
+RUN apk add musl-dev
-########################## BUILD IMAGE ##########################
-# Alpine build image to build Conduit's statically compiled binary
-FROM alpine:3.14 as builder
+# == Build dependencies without our own code separately for caching ==
+#
+# Need a fake main.rs since Cargo refuses to build anything otherwise.
+#
+# See https://github.com/rust-lang/cargo/issues/2644 for a Cargo feature
+# request that would allow just dependencies to be compiled, presumably
+# regardless of whether source files are available.
+RUN mkdir src && touch src/lib.rs && echo 'fn main() {}' > src/main.rs
+COPY Cargo.toml Cargo.lock ./
+RUN cargo build --release && rm -r src
+
+# Copy over actual Conduit sources
+COPY src src
+
+# main.rs and lib.rs need their timestamp updated for this to work correctly since
+# otherwise the build with the fake main.rs from above is newer than the
+# source files (COPY preserves timestamps).
+#
+# Builds conduit and places the binary at /usr/src/conduit/target/release/conduit
+RUN touch src/main.rs && touch src/lib.rs && cargo build --release
-# Install packages needed for building all crates
-RUN apk add --no-cache \
- cargo \
- openssl-dev
-
-# Specifies if the local project is build or if Conduit gets build
-# from the official git repository. Defaults to the git repo.
-ARG LOCAL=false
-# Specifies which revision/commit is build. Defaults to HEAD
-ARG GIT_REF=origin/master
-
-# Copy project files from current folder
-COPY . .
-# Build it from the copied local files or from the official git repository
-RUN if [[ $LOCAL == "true" ]]; then \
- mv ./docker/healthcheck.sh . ; \
- echo "Building from local source..." ; \
- cargo install --path . ; \
- else \
- echo "Building revision '${GIT_REF}' from online source..." ; \
- cargo install --git "https://gitlab.com/famedly/conduit.git" --rev ${GIT_REF} ; \
- echo "Loadings healthcheck script from online source..." ; \
- wget "https://gitlab.com/famedly/conduit/-/raw/${GIT_REF#origin/}/docker/healthcheck.sh" ; \
- fi
-
-########################## RUNTIME IMAGE ##########################
-# Create new stage with a minimal image for the actual
-# runtime image/container
-FROM alpine:3.14
-
-ARG CREATED
-ARG VERSION
-ARG GIT_REF=origin/master
-ENV CONDUIT_CONFIG="/srv/conduit/conduit.toml"
-# Labels according to https://github.com/opencontainers/image-spec/blob/master/annotations.md
-# including a custom label specifying the build command
-LABEL org.opencontainers.image.created=${CREATED} \
- org.opencontainers.image.authors="Conduit Contributors" \
- org.opencontainers.image.title="Conduit" \
- org.opencontainers.image.version=${VERSION} \
- org.opencontainers.image.vendor="Conduit Contributors" \
- org.opencontainers.image.description="A Matrix homeserver written in Rust" \
- org.opencontainers.image.url="https://conduit.rs/" \
- org.opencontainers.image.revision=${GIT_REF} \
- org.opencontainers.image.source="https://gitlab.com/famedly/conduit.git" \
- org.opencontainers.image.licenses="Apache-2.0" \
- org.opencontainers.image.documentation="" \
- org.opencontainers.image.ref.name="" \
- org.label-schema.docker.build="docker build . -t matrixconduit/matrix-conduit:latest --build-arg CREATED=$(date -u +'%Y-%m-%dT%H:%M:%SZ') --build-arg VERSION=$(grep -m1 -o '[0-9].[0-9].[0-9]' Cargo.toml)" \
- maintainer="Weasy666"
-
-# Standard port on which Conduit launches. You still need to map the port when using the docker command or docker-compose.
+
+# ---------------------------------------------------------------------------------------------------------------
+# Stuff below this line actually ends up in the resulting docker image
+# ---------------------------------------------------------------------------------------------------------------
+FROM docker.io/alpine:3.14 AS runner
+
+# Standard port on which Conduit launches.
+# You still need to map the port when using the docker command or docker-compose.
EXPOSE 6167
-# Copy config files from context and the binary from
-# the "builder" stage to the current stage into folder
-# /srv/conduit and create data folder for database
+# Note from @jfowl: I would like to remove this in the future and just have the Docker version be configured with envs.
+ENV CONDUIT_CONFIG="/srv/conduit/conduit.toml"
+
+# Conduit needs:
+# ca-certificates: for https
+# libgcc: Apparently this is needed, even if I (@jfowl) don't know exactly why. But whatever, it's not that big.
+RUN apk add --no-cache \
+ ca-certificates \
+ curl \
+ libgcc
+
+
+# Created directory for the database and media files
RUN mkdir -p /srv/conduit/.local/share/conduit
-COPY --from=builder /root/.cargo/bin/conduit /srv/conduit/
-COPY --from=builder ./healthcheck.sh /srv/conduit/
+# Test if Conduit is still alive, uses the same endpoint as Element
+COPY ./docker/healthcheck.sh /srv/conduit/
+HEALTHCHECK --start-period=5s --interval=5s CMD ./healthcheck.sh
+
+# Copy over the actual Conduit binary from the builder stage
+COPY --from=builder /usr/src/conduit/target/release/conduit /srv/conduit/
+
+# Improve security: Don't run stuff as root, that does not need to run as root:
# Add www-data user and group with UID 82, as used by alpine
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install
RUN set -x ; \
@@ -79,19 +70,13 @@ RUN set -x ; \
# Change ownership of Conduit files to www-data user and group
RUN chown -cR www-data:www-data /srv/conduit
+RUN chmod +x /srv/conduit/healthcheck.sh
-# Install packages needed to run Conduit
-RUN apk add --no-cache \
- ca-certificates \
- curl \
- libgcc
-
-# Test if Conduit is still alive, uses the same endpoint as Element
-HEALTHCHECK --start-period=5s --interval=60s CMD ./healthcheck.sh
-
-# Set user to www-data
+# Change user to www-data
USER www-data
# Set container home directory
WORKDIR /srv/conduit
-# Run Conduit
-ENTRYPOINT [ "/srv/conduit/conduit" ]
+
+# Run Conduit and print backtraces on panics
+ENV RUST_BACKTRACE=1
+ENTRYPOINT [ "/srv/conduit/conduit" ] \ No newline at end of file