Skip to content

Commit e043329

Browse files
committed
Produce a distroless-based Docker image
1 parent eedab12 commit e043329

File tree

1 file changed

+68
-42
lines changed

1 file changed

+68
-42
lines changed

docker/Dockerfile

+68-42
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,17 @@
2020
# `poetry export | pip install -r /dev/stdin`, but beware: we have experienced bugs in
2121
# in `poetry export` in the past.
2222

23-
ARG PYTHON_VERSION=3.12
23+
ARG PYTHON_VERSION=3.13
2424

2525
###
2626
### Stage 0: generate requirements.txt
2727
###
28-
# We hardcode the use of Debian bookworm here because this could change upstream
29-
# and other Dockerfiles used for testing are expecting bookworm.
30-
FROM docker.io/library/python:${PYTHON_VERSION}-slim-bookworm AS requirements
28+
### This stage is platform-agnostic, so we can use the build platform in case of cross-compilation.
29+
###
30+
FROM --platform=$BUILDPLATFORM docker.io/library/python:${PYTHON_VERSION}-slim-bookworm AS requirements
31+
32+
# Tell apt to keep downloaded package files, as we're using cache mounts.
33+
RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
3134

3235
# RUN --mount is specific to buildkit and is documented at
3336
# https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md#build-mounts-run---mount.
@@ -37,23 +40,7 @@ RUN \
3740
--mount=type=cache,target=/var/cache/apt,sharing=locked \
3841
--mount=type=cache,target=/var/lib/apt,sharing=locked \
3942
apt-get update -qq && apt-get install -yqq \
40-
build-essential curl git libffi-dev libssl-dev pkg-config \
41-
&& rm -rf /var/lib/apt/lists/*
42-
43-
# Install rust and ensure its in the PATH.
44-
# (Rust may be needed to compile `cryptography`---which is one of poetry's
45-
# dependencies---on platforms that don't have a `cryptography` wheel.
46-
ENV RUSTUP_HOME=/rust
47-
ENV CARGO_HOME=/cargo
48-
ENV PATH=/cargo/bin:/rust/bin:$PATH
49-
RUN mkdir /rust /cargo
50-
51-
RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --default-toolchain stable --profile minimal
52-
53-
# arm64 builds consume a lot of memory if `CARGO_NET_GIT_FETCH_WITH_CLI` is not
54-
# set to true, so we expose it as a build-arg.
55-
ARG CARGO_NET_GIT_FETCH_WITH_CLI=false
56-
ENV CARGO_NET_GIT_FETCH_WITH_CLI=$CARGO_NET_GIT_FETCH_WITH_CLI
43+
build-essential curl git libffi-dev libssl-dev pkg-config
5744

5845
# We install poetry in its own build stage to avoid its dependencies conflicting with
5946
# synapse's dependencies.
@@ -89,6 +76,9 @@ RUN if [ -z "$TEST_ONLY_IGNORE_POETRY_LOCKFILE" ]; then \
8976
###
9077
FROM docker.io/library/python:${PYTHON_VERSION}-slim-bookworm AS builder
9178

79+
# Tell apt to keep downloaded package files, as we're using cache mounts.
80+
RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
81+
9282
# install the OS build deps
9383
RUN \
9484
--mount=type=cache,target=/var/cache/apt,sharing=locked \
@@ -107,8 +97,7 @@ RUN \
10797
git \
10898
curl \
10999
libicu-dev \
110-
pkg-config \
111-
&& rm -rf /var/lib/apt/lists/*
100+
pkg-config
112101

113102

114103
# Install rust and ensure its in the PATH
@@ -155,32 +144,69 @@ RUN --mount=type=cache,target=/synapse/target,sharing=locked \
155144
fi
156145

157146
###
158-
### Stage 2: runtime
147+
## Stage 2: runtime dependencies download for ARM64 and AMD64
159148
###
149+
FROM --platform=$BUILDPLATFORM ghcr.io/astral-sh/uv:bookworm-slim AS runtime-deps
160150

161-
FROM docker.io/library/python:${PYTHON_VERSION}-slim-bookworm
151+
# Tell apt to keep downloaded package files, as we're using cache mounts.
152+
RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
162153

163-
LABEL org.opencontainers.image.url='https://matrix.org/docs/projects/server/synapse'
164-
LABEL org.opencontainers.image.documentation='https://github.com/element-hq/synapse/blob/master/docker/README.md'
165-
LABEL org.opencontainers.image.source='https://github.com/element-hq/synapse.git'
166-
LABEL org.opencontainers.image.licenses='AGPL-3.0-or-later'
154+
# Add both target architectures
155+
RUN dpkg --add-architecture arm64
156+
RUN dpkg --add-architecture amd64
157+
158+
ARG PYTHON_VERSION
159+
160+
ENV UV_PYTHON_INSTALL_DIR=/tmp/uv-python-install
161+
RUN uv python install \
162+
cpython-${PYTHON_VERSION}-linux-aarch64-gnu \
163+
cpython-${PYTHON_VERSION}-linux-x86_64_v2-gnu
164+
165+
RUN mkdir -p /install-amd64/usr /install-arm64/usr
166+
RUN mv ${UV_PYTHON_INSTALL_DIR}/cpython-*-linux-aarch64-gnu/ /install-arm64/usr/local
167+
RUN mv ${UV_PYTHON_INSTALL_DIR}/cpython-*-linux-x86_64_v2-gnu/ /install-amd64/usr/local
167168

168169
RUN \
169170
--mount=type=cache,target=/var/cache/apt,sharing=locked \
170171
--mount=type=cache,target=/var/lib/apt,sharing=locked \
171-
apt-get update -qq && apt-get install -yqq \
172-
curl \
173-
gosu \
174-
libjpeg62-turbo \
175-
libpq5 \
176-
libwebp7 \
177-
xmlsec1 \
178-
libjemalloc2 \
179-
libicu72 \
180-
libssl-dev \
181-
openssl \
182-
&& rm -rf /var/lib/apt/lists/*
172+
apt-get update -qq && \
173+
for arch in arm64 amd64; do \
174+
mkdir -p /tmp/debs-${arch} && \
175+
cd /tmp/debs-${arch} && \
176+
apt-get download \
177+
gosu:${arch} \
178+
libjpeg62-turbo:${arch} \
179+
libpq5:${arch} \
180+
libwebp7:${arch} \
181+
xmlsec1:${arch} \
182+
libjemalloc2:${arch} \
183+
libicu72:${arch} \
184+
zlib1g:${arch} \
185+
&& \
186+
mkdir -p /install-${arch}/var/lib/dpkg/status.d/ && \
187+
for deb in *.deb; do \
188+
package_name=$(dpkg-deb -I ${deb} | awk '/^ Package: .*$/ {print $2}'); \
189+
echo "Process: ${package_name}"; \
190+
dpkg --ctrl-tarfile $deb | tar -Oxvf - ./control > /install-${arch}/var/lib/dpkg/status.d/${package_name}; \
191+
dpkg --extract $deb /install-${arch} || exit 10; \
192+
done \
193+
done
194+
195+
196+
###
197+
### Stage 3: runtime
198+
###
199+
200+
FROM gcr.io/distroless/cc-debian12:debug
201+
202+
ARG TARGETARCH
203+
204+
LABEL org.opencontainers.image.url='https://matrix.org/docs/projects/server/synapse'
205+
LABEL org.opencontainers.image.documentation='https://github.com/element-hq/synapse/blob/master/docker/README.md'
206+
LABEL org.opencontainers.image.source='https://github.com/element-hq/synapse.git'
207+
LABEL org.opencontainers.image.licenses='AGPL-3.0-or-later'
183208

209+
COPY --from=runtime-deps /install-${TARGETARCH} /
184210
COPY --from=builder /install /usr/local
185211
COPY ./docker/start.py /start.py
186212
COPY ./docker/conf /conf
@@ -190,4 +216,4 @@ EXPOSE 8008/tcp 8009/tcp 8448/tcp
190216
ENTRYPOINT ["/start.py"]
191217

192218
HEALTHCHECK --start-period=5s --interval=15s --timeout=5s \
193-
CMD curl -fSs http://localhost:8008/health || exit 1
219+
CMD wget --no-verbose --tries=1 --spider http://localhost:8008/health

0 commit comments

Comments
 (0)