Browse Source

Improve local Docker builds

This has nothing to do with the CI docker builds, but imrpoves the situation for people who want to build their own docker image.

It adds some caching magic for compiling dependencies, cleans up the file and adds loads of comments.
merge-requests/225/head
Jonas Zohren 4 years ago
parent
commit
680188e232
No known key found for this signature in database
GPG Key ID: FE3ED5D90A175463
  1. 2
      .dockerignore
  2. 136
      Dockerfile

2
.dockerignore

@ -14,6 +14,8 @@ docker-compose*
# Git folder # Git folder
.git .git
.gitea .gitea
.gitlab
.github
# Dot files # Dot files
.env .env

136
Dockerfile

@ -1,97 +1,59 @@
# Using multistage build: # syntax=docker/dockerfile:1
# https://docs.docker.com/develop/develop-images/multistage-build/ FROM docker.io/rust:1.53-alpine AS builder
# https://whitfin.io/speeding-up-rust-docker-builds/ WORKDIR /usr/src/conduit
# Install required packages to build Conduit and it's dependencies
########################## BUILD IMAGE ########################## RUN apk add musl-dev
# 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 ==
#
# Install packages needed for building all crates # 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
# ---------------------------------------------------------------------------------------------------------------
# Stuff below this line actually ends up in the resulting docker image
# ---------------------------------------------------------------------------------------------------------------
FROM docker.io/alpine:3.14 AS runner
# Conduit needs:
# ca-certificates: for https
# curl: for the container's healtcheck
# 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 \ RUN apk add --no-cache \
cargo \ ca-certificates \
openssl-dev curl \
libgcc
# 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 ########################## # Created directory for the database and media files
# Create new stage with a minimal image for the actual RUN mkdir -p /srv/conduit/.local/share/conduit
# runtime image/container
FROM alpine:3.14
ARG CREATED # Copy over the actual Conduit binary from the builder stage
ARG VERSION COPY --from=builder /usr/src/conduit/target/release/conduit /srv/conduit/
ARG GIT_REF=origin/master
# 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" ENV CONDUIT_CONFIG="/srv/conduit/conduit.toml"
# Labels according to https://github.com/opencontainers/image-spec/blob/master/annotations.md # Not strictly needed, but documents the port.
# 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.
EXPOSE 6167 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
RUN mkdir -p /srv/conduit/.local/share/conduit
COPY --from=builder /root/.cargo/bin/conduit /srv/conduit/
COPY --from=builder ./healthcheck.sh /srv/conduit/
# 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 ; \
addgroup -Sg 82 www-data 2>/dev/null ; \
adduser -S -D -H -h /srv/conduit -G www-data -g www-data www-data 2>/dev/null ; \
addgroup www-data www-data 2>/dev/null && exit 0 ; exit 1
# Change ownership of Conduit files to www-data user and group
RUN chown -cR www-data:www-data /srv/conduit
# 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
USER www-data
# Set container home directory
WORKDIR /srv/conduit WORKDIR /srv/conduit
# Run Conduit
ENTRYPOINT [ "/srv/conduit/conduit" ] ENTRYPOINT [ "/srv/conduit/conduit" ]

Loading…
Cancel
Save