From 4097ada89fefe12e7ec6d2b7a3bfbc61e64e14a0 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Wed, 30 Apr 2025 09:54:30 -0400 Subject: Optimize `Dockerfile-workers` (#18292) - Use a `uv:python` image for the first build layer, to reduce the number of intermediate images required, as the main Dockerfile uses that image already - Use a cache mount for `apt` commands - Skip a pointless install of `redis-server`, since the redis Docker image is copied from instead - Move some RUN steps out of the final image layer & into the build layer Depends on https://github.com/element-hq/synapse/pull/18275 ### Pull Request Checklist * [x] Pull request is based on the develop branch * [x] Pull request includes a [changelog file](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#changelog). The entry should: - Be a short description of your change which makes sense to users. "Fixed a bug that prevented receiving messages from other servers." instead of "Moved X method from `EventStore` to `EventWorkerStore`.". - Use markdown where necessary, mostly for `code blocks`. - End with either a period (.) or an exclamation mark (!). - Start with a capital letter. - Feel free to credit yourself, by adding a sentence "Contributed by @github_username." or "Contributed by [Your Name]." to the end of the entry. * [x] [Code style](https://element-hq.github.io/synapse/latest/code_style.html) is correct (run the [linters](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#run-the-linters)) --- changelog.d/18292.docker | 1 + docker/Dockerfile-workers | 50 +++++++++++++++++++++++++---------------------- 2 files changed, 28 insertions(+), 23 deletions(-) create mode 100644 changelog.d/18292.docker diff --git a/changelog.d/18292.docker b/changelog.d/18292.docker new file mode 100644 index 0000000000..cdb95b369b --- /dev/null +++ b/changelog.d/18292.docker @@ -0,0 +1 @@ +Optimize the build of the workers image. diff --git a/docker/Dockerfile-workers b/docker/Dockerfile-workers index dd0bf59994..a7f576184d 100644 --- a/docker/Dockerfile-workers +++ b/docker/Dockerfile-workers @@ -3,18 +3,37 @@ ARG SYNAPSE_VERSION=latest ARG FROM=matrixdotorg/synapse:$SYNAPSE_VERSION ARG DEBIAN_VERSION=bookworm +ARG PYTHON_VERSION=3.12 -# first of all, we create a base image with an nginx which we can copy into the +# first of all, we create a base image with dependencies which we can copy into the # target image. For repeated rebuilds, this is much faster than apt installing # each time. -FROM docker.io/library/debian:${DEBIAN_VERSION}-slim AS deps_base +FROM ghcr.io/astral-sh/uv:python${PYTHON_VERSION}-${DEBIAN_VERSION} AS deps_base + + # Tell apt to keep downloaded package files, as we're using cache mounts. + 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 + RUN \ --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update -qq && \ DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends \ - redis-server nginx-light + nginx-light + + RUN \ + # remove default page + rm /etc/nginx/sites-enabled/default && \ + # have nginx log to stderr/out + ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log + + # --link-mode=copy silences a warning as uv isn't able to do hardlinks between its cache + # (mounted as --mount=type=cache) and the target directory. + RUN --mount=type=cache,target=/root/.cache/uv \ + uv pip install --link-mode=copy --prefix="/uv/usr/local" supervisor~=4.2 + + RUN mkdir -p /uv/etc/supervisor/conf.d # Similarly, a base to copy the redis server from. # @@ -27,31 +46,16 @@ FROM docker.io/library/redis:7-${DEBIAN_VERSION} AS redis_base # now build the final image, based on the the regular Synapse docker image FROM $FROM - # Install supervisord with uv pip instead of apt, to avoid installing a second - # copy of python. - # --link-mode=copy silences a warning as uv isn't able to do hardlinks between its cache - # (mounted as --mount=type=cache) and the target directory. - RUN \ - --mount=type=bind,from=ghcr.io/astral-sh/uv:0.6.8,source=/uv,target=/uv \ - --mount=type=cache,target=/root/.cache/uv \ - /uv pip install --link-mode=copy --prefix="/usr/local" supervisor~=4.2 - - RUN mkdir -p /etc/supervisor/conf.d - - # Copy over redis and nginx + # Copy over dependencies COPY --from=redis_base /usr/local/bin/redis-server /usr/local/bin - + COPY --from=deps_base /uv / COPY --from=deps_base /usr/sbin/nginx /usr/sbin COPY --from=deps_base /usr/share/nginx /usr/share/nginx COPY --from=deps_base /usr/lib/nginx /usr/lib/nginx COPY --from=deps_base /etc/nginx /etc/nginx - RUN rm /etc/nginx/sites-enabled/default - RUN mkdir /var/log/nginx /var/lib/nginx - RUN chown www-data /var/lib/nginx - - # have nginx log to stderr/out - RUN ln -sf /dev/stdout /var/log/nginx/access.log - RUN ln -sf /dev/stderr /var/log/nginx/error.log + COPY --from=deps_base /var/log/nginx /var/log/nginx + # chown to allow non-root user to write to http-*-temp-path dirs + COPY --from=deps_base --chown=www-data:root /var/lib/nginx /var/lib/nginx # Copy Synapse worker, nginx and supervisord configuration template files COPY ./docker/conf-workers/* /conf/ -- cgit 1.5.1