# syntax=docker/dockerfile:1

ARG SYNAPSE_VERSION=latest
ARG FROM=matrixdotorg/synapse:$SYNAPSE_VERSION
ARG DEBIAN_VERSION=bookworm

# first of all, we create a base image with an nginx 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
    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

# Similarly, a base to copy the redis server from.
#
# The redis docker image has fewer dynamic libraries than the debian package,
# which makes it much easier to copy (but we need to make sure we use an image
# based on the same debian version as the synapse image, to make sure we get
# the expected version of libc.
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 --from=redis_base /usr/local/bin/redis-server /usr/local/bin

    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 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 /bin/sh /healthcheck.sh
