Browse Source
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
2 changed files with 51 additions and 87 deletions
@ -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…
Reference in new issue