Compare commits
7 Commits
develop
...
quenting/d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0535f631f5 | ||
|
|
f2188cf931 | ||
|
|
c4746a321d | ||
|
|
47e4c6eb79 | ||
|
|
b9fab43943 | ||
|
|
799bd77170 | ||
|
|
ab3f4dc5b5 |
14
.github/workflows/docker.yml
vendored
14
.github/workflows/docker.yml
vendored
@@ -4,8 +4,9 @@ name: Build docker images
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags: ["v*"]
|
# TEMP
|
||||||
branches: [ master, main, develop ]
|
# tags: ["v*"]
|
||||||
|
# branches: [ master, main, develop ]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -44,12 +45,16 @@ jobs:
|
|||||||
|
|
||||||
- name: Log in to DockerHub
|
- name: Log in to DockerHub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
|
# TEMP
|
||||||
|
if: ${{ false }}
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Log in to GHCR
|
- name: Log in to GHCR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
|
# TEMP
|
||||||
|
if: ${{ false }}
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
@@ -74,7 +79,8 @@ jobs:
|
|||||||
id: build-and-push
|
id: build-and-push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
push: true
|
# TEMP
|
||||||
|
push: false
|
||||||
labels: |
|
labels: |
|
||||||
gitsha1=${{ github.sha }}
|
gitsha1=${{ github.sha }}
|
||||||
org.opencontainers.image.version=${{ env.SYNAPSE_VERSION }}
|
org.opencontainers.image.version=${{ env.SYNAPSE_VERSION }}
|
||||||
@@ -88,6 +94,8 @@ jobs:
|
|||||||
CARGO_NET_GIT_FETCH_WITH_CLI=true
|
CARGO_NET_GIT_FETCH_WITH_CLI=true
|
||||||
|
|
||||||
- name: Sign the images with GitHub OIDC Token
|
- name: Sign the images with GitHub OIDC Token
|
||||||
|
# TEMP
|
||||||
|
if: ${{ false }}
|
||||||
env:
|
env:
|
||||||
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
||||||
TAGS: ${{ steps.set-tag.outputs.tags }}
|
TAGS: ${{ steps.set-tag.outputs.tags }}
|
||||||
|
|||||||
1
changelog.d/18039.docker
Normal file
1
changelog.d/18039.docker
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Use a [`distroless`](https://github.com/GoogleContainerTools/distroless) base runtime image.
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
# in `poetry export` in the past.
|
# in `poetry export` in the past.
|
||||||
|
|
||||||
ARG DEBIAN_VERSION=bookworm
|
ARG DEBIAN_VERSION=bookworm
|
||||||
|
ARG DEBIAN_VERSION_NUMERIC=12
|
||||||
ARG PYTHON_VERSION=3.12
|
ARG PYTHON_VERSION=3.12
|
||||||
ARG POETRY_VERSION=1.8.3
|
ARG POETRY_VERSION=1.8.3
|
||||||
|
|
||||||
@@ -116,9 +117,9 @@ RUN \
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
###
|
###
|
||||||
### Stage 2: runtime dependencies download for ARM64 and AMD64
|
## Stage 2: runtime dependencies download for ARM64 and AMD64
|
||||||
###
|
###
|
||||||
FROM --platform=$BUILDPLATFORM docker.io/library/debian:${DEBIAN_VERSION} AS runtime-deps
|
FROM --platform=$BUILDPLATFORM ghcr.io/astral-sh/uv:${DEBIAN_VERSION} AS runtime-deps
|
||||||
|
|
||||||
# Tell apt to keep downloaded package files, as we're using cache mounts.
|
# 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 rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
|
||||||
@@ -127,6 +128,15 @@ RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloa
|
|||||||
RUN dpkg --add-architecture arm64
|
RUN dpkg --add-architecture arm64
|
||||||
RUN dpkg --add-architecture amd64
|
RUN dpkg --add-architecture amd64
|
||||||
|
|
||||||
|
ARG PYTHON_VERSION
|
||||||
|
RUN uv python install \
|
||||||
|
cpython-${PYTHON_VERSION}-linux-aarch64-gnu \
|
||||||
|
cpython-${PYTHON_VERSION}-linux-x86_64_v2-gnu
|
||||||
|
|
||||||
|
RUN mkdir -p /install-amd64/usr/lib /install-arm64/usr/lib
|
||||||
|
RUN mv $(uv python dir)/cpython-*-linux-aarch64-gnu/ /install-arm64/usr/local
|
||||||
|
RUN mv $(uv python dir)/cpython-*-linux-x86_64_v2-gnu/ /install-amd64/usr/local
|
||||||
|
|
||||||
# Fetch the runtime dependencies debs for both architectures
|
# Fetch the runtime dependencies debs for both architectures
|
||||||
# We do that by building a recursive list of packages we need to download with `apt-cache depends`
|
# We do that by building a recursive list of packages we need to download with `apt-cache depends`
|
||||||
# and then downloading them with `apt-get download`.
|
# and then downloading them with `apt-get download`.
|
||||||
@@ -134,16 +144,16 @@ RUN \
|
|||||||
--mount=type=cache,target=/var/cache/apt,sharing=locked \
|
--mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||||
apt-get update -qq && \
|
apt-get update -qq && \
|
||||||
apt-get install -y --no-install-recommends rsync && \
|
|
||||||
apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends \
|
apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends \
|
||||||
curl \
|
|
||||||
gosu \
|
gosu \
|
||||||
|
zlib1g \
|
||||||
libjpeg62-turbo \
|
libjpeg62-turbo \
|
||||||
libpq5 \
|
libpq5 \
|
||||||
libwebp7 \
|
libwebp7 \
|
||||||
xmlsec1 \
|
xmlsec1 \
|
||||||
libjemalloc2 \
|
libjemalloc2 \
|
||||||
libicu \
|
libicu \
|
||||||
|
openssl \
|
||||||
| grep '^\w' > /tmp/pkg-list && \
|
| grep '^\w' > /tmp/pkg-list && \
|
||||||
for arch in arm64 amd64; do \
|
for arch in arm64 amd64; do \
|
||||||
mkdir -p /tmp/debs-${arch} && \
|
mkdir -p /tmp/debs-${arch} && \
|
||||||
@@ -152,10 +162,6 @@ RUN \
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Extract the debs for each architecture
|
# Extract the debs for each architecture
|
||||||
# On the runtime image, /lib is a symlink to /usr/lib, so we need to copy the
|
|
||||||
# libraries to the right place, else the `COPY` won't work.
|
|
||||||
# On amd64, we'll also have a /lib64 folder with ld-linux-x86-64.so.2, which is
|
|
||||||
# already present in the runtime image.
|
|
||||||
RUN \
|
RUN \
|
||||||
for arch in arm64 amd64; do \
|
for arch in arm64 amd64; do \
|
||||||
mkdir -p /install-${arch}/var/lib/dpkg/status.d/ && \
|
mkdir -p /install-${arch}/var/lib/dpkg/status.d/ && \
|
||||||
@@ -165,8 +171,6 @@ RUN \
|
|||||||
dpkg --ctrl-tarfile $deb | tar -Ox ./control > /install-${arch}/var/lib/dpkg/status.d/${package_name}; \
|
dpkg --ctrl-tarfile $deb | tar -Ox ./control > /install-${arch}/var/lib/dpkg/status.d/${package_name}; \
|
||||||
dpkg --extract $deb /install-${arch}; \
|
dpkg --extract $deb /install-${arch}; \
|
||||||
done; \
|
done; \
|
||||||
rsync -avr /install-${arch}/lib/ /install-${arch}/usr/lib; \
|
|
||||||
rm -rf /install-${arch}/lib /install-${arch}/lib64; \
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
@@ -174,7 +178,7 @@ RUN \
|
|||||||
### Stage 3: runtime
|
### Stage 3: runtime
|
||||||
###
|
###
|
||||||
|
|
||||||
FROM docker.io/library/python:${PYTHON_VERSION}-slim-${DEBIAN_VERSION}
|
FROM gcr.io/distroless/base-nossl-debian${DEBIAN_VERSION_NUMERIC}:debug
|
||||||
|
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
|
|
||||||
@@ -190,7 +194,8 @@ COPY ./docker/conf /conf
|
|||||||
|
|
||||||
EXPOSE 8008/tcp 8009/tcp 8448/tcp
|
EXPOSE 8008/tcp 8009/tcp 8448/tcp
|
||||||
|
|
||||||
|
SHELL ["/busybox/sh", "-c"]
|
||||||
ENTRYPOINT ["/start.py"]
|
ENTRYPOINT ["/start.py"]
|
||||||
|
|
||||||
HEALTHCHECK --start-period=5s --interval=15s --timeout=5s \
|
HEALTHCHECK --start-period=5s --interval=15s --timeout=5s \
|
||||||
CMD curl -fSs http://localhost:8008/health || exit 1
|
CMD wget --quiet --tries=1 --spider http://localhost:8008/health || exit 1
|
||||||
|
|||||||
@@ -2,66 +2,76 @@
|
|||||||
|
|
||||||
ARG SYNAPSE_VERSION=latest
|
ARG SYNAPSE_VERSION=latest
|
||||||
ARG FROM=matrixdotorg/synapse:$SYNAPSE_VERSION
|
ARG FROM=matrixdotorg/synapse:$SYNAPSE_VERSION
|
||||||
|
ARG DEBIAN_VERSION=bookworm
|
||||||
|
ARG DEBIAN_VERSION_NUMERIC=12
|
||||||
|
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 an nginx which we can copy into the
|
||||||
# target image. For repeated rebuilds, this is much faster than apt installing
|
# target image. For repeated rebuilds, this is much faster than apt installing
|
||||||
# each time.
|
# each time.
|
||||||
|
|
||||||
FROM docker.io/library/debian:bookworm-slim AS deps_base
|
FROM ghcr.io/astral-sh/uv:python${PYTHON_VERSION}-${DEBIAN_VERSION} 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.
|
# This silences a warning as uv isn't able to do hardlinks between its cache
|
||||||
#
|
# (mounted as --mount=type=cache) and the target directory.
|
||||||
# The redis docker image has fewer dynamic libraries than the debian package,
|
ENV UV_LINK_MODE=copy
|
||||||
# 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
|
RUN \
|
||||||
# the expected version of libc.
|
--mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||||
FROM docker.io/library/redis:7-bookworm AS redis_base
|
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||||
|
apt-get update -qq && \
|
||||||
|
apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends \
|
||||||
|
redis-server \
|
||||||
|
nginx-light \
|
||||||
|
mawk \
|
||||||
|
| grep '^\w' > /tmp/pkg-list && \
|
||||||
|
mkdir -p /tmp/debs && \
|
||||||
|
cat /tmp/pkg-list && \
|
||||||
|
cd /tmp/debs && \
|
||||||
|
xargs apt-get download </tmp/pkg-list
|
||||||
|
|
||||||
|
# Extract the debs for each architecture
|
||||||
|
RUN \
|
||||||
|
mkdir -p /install/var/lib/dpkg/status.d/ && \
|
||||||
|
for deb in /tmp/debs/*.deb; do \
|
||||||
|
package_name=$(dpkg-deb -I ${deb} | awk '/^ Package: .*$/ {print $2}'); \
|
||||||
|
echo "Extracting: ${package_name}"; \
|
||||||
|
dpkg --ctrl-tarfile $deb | tar -Ox ./control > /install/var/lib/dpkg/status.d/${package_name}; \
|
||||||
|
dpkg --extract $deb /install; \
|
||||||
|
done;
|
||||||
|
|
||||||
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
|
uv pip install --prefix="/install/usr/local" supervisor~=4.2
|
||||||
|
|
||||||
# now build the final image, based on the the regular Synapse docker image
|
# now build the final image, based on the the regular Synapse docker image
|
||||||
FROM $FROM
|
FROM $FROM
|
||||||
|
|
||||||
# Install supervisord with pip instead of apt, to avoid installing a second
|
# Copy over redis, nginx and supervisor
|
||||||
# copy of python.
|
COPY --from=deps_base /install /
|
||||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
RUN mkdir -p /etc/supervisor/conf.d
|
||||||
pip install supervisor~=4.2
|
RUN addgroup -S -g 33 www-data
|
||||||
RUN mkdir -p /etc/supervisor/conf.d
|
RUN adduser -S -u 33 -G www-data -h /var/www -s /usr/sbin/nologin -H www-data
|
||||||
|
RUN chown www-data /var/lib/nginx
|
||||||
|
|
||||||
# Copy over redis and nginx
|
# have nginx log to stderr/out
|
||||||
COPY --from=redis_base /usr/local/bin/redis-server /usr/local/bin
|
RUN ln -sf /dev/stdout /var/log/nginx/access.log
|
||||||
|
RUN ln -sf /dev/stderr /var/log/nginx/error.log
|
||||||
|
|
||||||
COPY --from=deps_base /usr/sbin/nginx /usr/sbin
|
# Copy Synapse worker, nginx and supervisord configuration template files
|
||||||
COPY --from=deps_base /usr/share/nginx /usr/share/nginx
|
COPY ./docker/conf-workers/* /conf/
|
||||||
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
|
# Copy a script to prefix log lines with the supervisor program name
|
||||||
RUN ln -sf /dev/stdout /var/log/nginx/access.log
|
COPY ./docker/prefix-log /usr/local/bin/
|
||||||
RUN ln -sf /dev/stderr /var/log/nginx/error.log
|
|
||||||
|
|
||||||
# Copy Synapse worker, nginx and supervisord configuration template files
|
# Expose nginx listener port
|
||||||
COPY ./docker/conf-workers/* /conf/
|
EXPOSE 8080/tcp
|
||||||
|
|
||||||
# Copy a script to prefix log lines with the supervisor program name
|
# A script to read environment variables and create the necessary
|
||||||
COPY ./docker/prefix-log /usr/local/bin/
|
# 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"]
|
||||||
|
|
||||||
# Expose nginx listener port
|
# Replace the healthcheck with one which checks *all* the workers. The script
|
||||||
EXPOSE 8080/tcp
|
# is generated by configure_workers_and_start.py.
|
||||||
|
HEALTHCHECK --start-period=5s --interval=15s --timeout=5s \
|
||||||
# A script to read environment variables and create the necessary
|
CMD /bin/sh /healthcheck.sh
|
||||||
# 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
|
|
||||||
|
|||||||
@@ -15,13 +15,15 @@ FROM $FROM
|
|||||||
# since for repeated rebuilds, this is much faster than apt installing
|
# since for repeated rebuilds, this is much faster than apt installing
|
||||||
# postgres each time.
|
# postgres each time.
|
||||||
|
|
||||||
# This trick only works because (a) the Synapse image happens to have all the
|
# This trick only works because we use a postgres image based on the same debian
|
||||||
# shared libraries that postgres wants, (b) we use a postgres image based on
|
# version as Synapse's docker image (so the versions of the shared libraries
|
||||||
# the same debian version as Synapse's docker image (so the versions of the
|
# match).
|
||||||
# shared libraries match).
|
RUN echo "nogroup:x:65534:" >> /etc/group
|
||||||
RUN adduser --system --uid 999 postgres --home /var/lib/postgresql
|
RUN adduser --system --uid 999 postgres --home /var/lib/postgresql
|
||||||
COPY --from=docker.io/library/postgres:13-bookworm /usr/lib/postgresql /usr/lib/postgresql
|
COPY --from=docker.io/library/postgres:13-bookworm /usr/lib /usr/lib
|
||||||
COPY --from=docker.io/library/postgres:13-bookworm /usr/share/postgresql /usr/share/postgresql
|
COPY --from=docker.io/library/postgres:13-bookworm /usr/share/postgresql /usr/share/postgresql
|
||||||
|
# initdb expects /bin/sh to be available
|
||||||
|
RUN ln -s /busybox/sh /bin/sh
|
||||||
RUN mkdir /var/run/postgresql && chown postgres /var/run/postgresql
|
RUN mkdir /var/run/postgresql && chown postgres /var/run/postgresql
|
||||||
ENV PATH="${PATH}:/usr/lib/postgresql/13/bin"
|
ENV PATH="${PATH}:/usr/lib/postgresql/13/bin"
|
||||||
ENV PGDATA=/var/lib/postgresql/data
|
ENV PGDATA=/var/lib/postgresql/data
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Default ENTRYPOINT for the docker image used for testing synapse with workers under complement
|
# Default ENTRYPOINT for the docker image used for testing synapse with workers under complement
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# This healthcheck script is designed to return OK when every
|
# This healthcheck script is designed to return OK when every
|
||||||
# host involved returns OK
|
# host involved returns OK
|
||||||
{%- for healthcheck_url in healthcheck_urls %}
|
{%- for healthcheck_url in healthcheck_urls %}
|
||||||
curl -fSs {{ healthcheck_url }} || exit 1
|
wget --quiet --tries=1 --spider {{ healthcheck_url }} || exit 1
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/local/bin/python
|
||||||
#
|
#
|
||||||
# This file is licensed under the Affero General Public License (AGPL) version 3.
|
# This file is licensed under the Affero General Public License (AGPL) version 3.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Prefixes all lines on stdout and stderr with the process name (as determined by
|
# Prefixes all lines on stdout and stderr with the process name (as determined by
|
||||||
# the SUPERVISOR_PROCESS_NAME env var, which is automatically set by Supervisor).
|
# the SUPERVISOR_PROCESS_NAME env var, which is automatically set by Supervisor).
|
||||||
@@ -10,6 +10,6 @@
|
|||||||
# '-W interactive' is a `mawk` extension which disables buffering on stdout and sets line-buffered reads on
|
# '-W interactive' is a `mawk` extension which disables buffering on stdout and sets line-buffered reads on
|
||||||
# stdin. The effect is that the output is flushed after each line, rather than being batched, which helps reduce
|
# stdin. The effect is that the output is flushed after each line, rather than being batched, which helps reduce
|
||||||
# confusion due to to interleaving of the different processes.
|
# confusion due to to interleaving of the different processes.
|
||||||
exec 1> >(awk -W interactive '{print "'"${SUPERVISOR_PROCESS_NAME}"' | "$0 }' >&1)
|
exec 1> >(mawk -W interactive '{print "'"${SUPERVISOR_PROCESS_NAME}"' | "$0; fflush() }' >&1)
|
||||||
exec 2> >(awk -W interactive '{print "'"${SUPERVISOR_PROCESS_NAME}"' | "$0 }' >&2)
|
exec 2> >(mawk -W interactive '{print "'"${SUPERVISOR_PROCESS_NAME}"' | "$0; fflush() }' >&2)
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user