# syntax=docker/dockerfile:1-labs ARG SYNAPSE_VERSION=latest ARG FROM=matrixdotorg/synapse:$SYNAPSE_VERSION ARG DEBIAN_VERSION=trixie ARG PYTHON_VERSION=3.13 ARG REDIS_VERSION=7.2 # 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 ghcr.io/astral-sh/uv:python${PYTHON_VERSION}-${DEBIAN_VERSION} AS deps_base ARG DEBIAN_VERSION ARG REDIS_VERSION # 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 # The upstream redis-server deb has fewer dynamic libraries than Debian's package which makes it easier to copy later on RUN \ curl -fsSL https://packages.redis.io/gpg | gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg && \ chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg && \ echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb ${DEBIAN_VERSION} main" | tee /etc/apt/sources.list.d/redis.list 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 \ nginx-light \ redis-server="6:${REDIS_VERSION}.*" redis-tools="6:${REDIS_VERSION}.*" \ # libicu is required by postgres, see `docker/complement/Dockerfile` libicu76 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 # now build the final image, based on the the regular Synapse docker image FROM $FROM # Copy over dependencies COPY --from=deps_base --parents /usr/lib/*-linux-gnu/libicu* / COPY --from=deps_base /usr/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 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/ # Copy a script to prefix log lines with the supervisor program name COPY ./docker/prefix-log /usr/local/bin/ # Expose nginx listener port EXPOSE 8080/tcp # A script to read environment variables and create the necessary # files to run the desired worker configuration. Will start supervisord. COPY ./docker/configure_workers_and_start.py /configure_workers_and_start.py ENTRYPOINT ["/configure_workers_and_start.py"] # Replace the healthcheck with one which checks *all* the workers. The script # is generated by configure_workers_and_start.py. HEALTHCHECK --start-period=5s --interval=15s --timeout=5s \ CMD ["/healthcheck.sh"]