Add support for Synapse container image customization

This allows people to augment the Synapse image with custom tools and
addons without having to rebuild it from scratch.

If customizations are enabled, the playbook will build a new
`localhost/matrixdotorg/synapse:VERSION-customized` image
on top of the default one (`FROM matrixdotorg/synapse:VERSION`)
and with custom Dockerfile build steps.

For servers that self-build the Synapse image, the Synapse image will be
built first, before proceding to extend it the same way.

In the future, we'll also have easy to enable Dockerfile build steps
for modules that the playbook supports.
This commit is contained in:
Slavi Pantaleev 2022-10-14 16:33:19 +03:00
parent 0da068c7e6
commit 881fdd28f0
8 changed files with 63 additions and 4 deletions

View file

@ -83,7 +83,7 @@
--mount type=bind,src={{ matrix_synapse_config_dir_path }},dst=/data --mount type=bind,src={{ matrix_synapse_config_dir_path }},dst=/data
--mount type=bind,src={{ matrix_synapse_config_dir_path }},dst=/matrix-media-store-parent/media-store --mount type=bind,src={{ matrix_synapse_config_dir_path }},dst=/matrix-media-store-parent/media-store
--mount type=bind,src={{ server_path_homeserver_db }},dst=/{{ server_path_homeserver_db | basename }} --mount type=bind,src={{ server_path_homeserver_db }},dst=/{{ server_path_homeserver_db | basename }}
{{ matrix_synapse_docker_image }} {{ matrix_synapse_docker_image_final }}
/usr/local/bin/synapse_port_db --sqlite-database /{{ server_path_homeserver_db | basename }} --postgres-config /data/homeserver.yaml /usr/local/bin/synapse_port_db --sqlite-database /{{ server_path_homeserver_db | basename }} --postgres-config /data/homeserver.yaml
register: matrix_postgres_import_synapse_sqlite_db_result register: matrix_postgres_import_synapse_sqlite_db_result
changed_when: matrix_postgres_import_synapse_sqlite_db_result.rc == 0 changed_when: matrix_postgres_import_synapse_sqlite_db_result.rc == 0

View file

@ -7,14 +7,47 @@ matrix_synapse_enabled: true
matrix_synapse_container_image_self_build: false matrix_synapse_container_image_self_build: false
matrix_synapse_container_image_self_build_repo: "https://github.com/matrix-org/synapse.git" matrix_synapse_container_image_self_build_repo: "https://github.com/matrix-org/synapse.git"
# matrix_synapse_container_image_customizations_enabled controls whether a customized Synapse image will be built.
#
# We toggle this variable to `true` when certain features which require a custom build are enabled.
# Feel free to toggle this to `true` yourself and specify build steps in `matrix_synapse_container_image_customizations_dockerfile_body_custom`.
#
# See:
# - `roles/matrix-synapse/templates/synapse/customizations/Dockerfile.j2`
# - `matrix_synapse_container_image_customizations_dockerfile_body_custom`
# - `matrix_synapse_docker_image_customized`
# - `matrix_synapse_docker_image_final`
matrix_synapse_container_image_customizations_enabled: "{{ matrix_synapse_ext_synapse_s3_storage_provider_enabled }}"
# matrix_synapse_container_image_customizations_dockerfile_body contains your custom Dockerfile steps
# for building your customized Synapse image based on the original (upstream) image (`matrix_synapse_docker_image`).
# A `FROM ...` clause is included automatically so you don't have to.
#
# Example:
# matrix_synapse_container_image_customizations_dockerfile_body_custom: |
# RUN echo 'This is a custom step for building the customized Docker image for Synapse.'
# RUN echo 'You can override matrix_synapse_container_image_customizations_dockerfile_body_custom to add your own steps.'
# RUN echo 'Note that matrix_synapse_container_image_customizations_dockerfile_body_auto injects steps before this.'
# RUN echo 'You do NOT need to include a FROM clause yourself.'
matrix_synapse_container_image_customizations_dockerfile_body_custom: ''
matrix_synapse_docker_image: "{{ matrix_synapse_docker_image_name_prefix }}matrixdotorg/synapse:{{ matrix_synapse_docker_image_tag }}" matrix_synapse_docker_image: "{{ matrix_synapse_docker_image_name_prefix }}matrixdotorg/synapse:{{ matrix_synapse_docker_image_tag }}"
matrix_synapse_docker_image_name_prefix: "{{ 'localhost/' if matrix_synapse_container_image_self_build else matrix_container_global_registry_prefix }}" matrix_synapse_docker_image_name_prefix: "{{ 'localhost/' if matrix_synapse_container_image_self_build else matrix_container_global_registry_prefix }}"
matrix_synapse_version: v1.68.0 matrix_synapse_version: v1.68.0
matrix_synapse_docker_image_tag: "{{ matrix_synapse_version }}" matrix_synapse_docker_image_tag: "{{ matrix_synapse_version }}"
matrix_synapse_docker_image_force_pull: "{{ matrix_synapse_docker_image.endswith(':latest') }}" matrix_synapse_docker_image_force_pull: "{{ matrix_synapse_docker_image.endswith(':latest') }}"
# matrix_synapse_docker_image_customized is the name of the locally built Synapse image
# which adds various customizations on top of the original (upstream) Synapse image.
# This image will be based on the upstream `matrix_synapse_docker_image` image, only if `matrix_synapse_container_image_customizations_enabled: true`.
matrix_synapse_docker_image_customized: "localhost/matrixdotorg/synapse:{{ matrix_synapse_docker_image_tag }}-customized"
# matrix_synapse_docker_image_final holds the name of the Synapse image to run depending on whether or not customizations are enabled.
matrix_synapse_docker_image_final: "{{ matrix_synapse_docker_image_customized if matrix_synapse_container_image_customizations_enabled else matrix_synapse_docker_image }} "
matrix_synapse_base_path: "{{ matrix_base_data_path }}/synapse" matrix_synapse_base_path: "{{ matrix_base_data_path }}/synapse"
matrix_synapse_docker_src_files_path: "{{ matrix_synapse_base_path }}/docker-src" matrix_synapse_docker_src_files_path: "{{ matrix_synapse_base_path }}/docker-src"
matrix_synapse_customized_docker_src_files_path: "{{ matrix_synapse_base_path }}/customized-docker-src"
matrix_synapse_config_dir_path: "{{ matrix_synapse_base_path }}/config" matrix_synapse_config_dir_path: "{{ matrix_synapse_base_path }}/config"
matrix_synapse_storage_path: "{{ matrix_synapse_base_path }}/storage" matrix_synapse_storage_path: "{{ matrix_synapse_base_path }}/storage"
matrix_synapse_media_store_path: "{{ matrix_synapse_storage_path }}/media-store" matrix_synapse_media_store_path: "{{ matrix_synapse_storage_path }}/media-store"

View file

@ -11,6 +11,7 @@
- {path: "{{ matrix_synapse_config_dir_path }}", when: true} - {path: "{{ matrix_synapse_config_dir_path }}", when: true}
- {path: "{{ matrix_synapse_ext_path }}", when: true} - {path: "{{ matrix_synapse_ext_path }}", when: true}
- {path: "{{ matrix_synapse_docker_src_files_path }}", when: "{{ matrix_synapse_container_image_self_build }}"} - {path: "{{ matrix_synapse_docker_src_files_path }}", when: "{{ matrix_synapse_container_image_self_build }}"}
- {path: "{{ matrix_synapse_customized_docker_src_files_path }}", when: "{{ matrix_synapse_container_image_customizations_enabled }}"}
# We handle matrix_synapse_media_store_path elsewhere (in ./synapse/setup_install.yml), # We handle matrix_synapse_media_store_path elsewhere (in ./synapse/setup_install.yml),
# because if it's using Goofys and it's already mounted (from before), # because if it's using Goofys and it's already mounted (from before),
# trying to chown/chmod it here will cause trouble. # trying to chown/chmod it here will cause trouble.

View file

@ -62,6 +62,25 @@
delay: "{{ matrix_container_retries_delay }}" delay: "{{ matrix_container_retries_delay }}"
until: result is not failed until: result is not failed
- when: "matrix_synapse_container_image_customizations_enabled | bool"
block:
- name: Ensure customizations Dockerfile is created
ansible.builtin.template:
src: "{{ role_path }}/templates/synapse/customizations/Dockerfile.j2"
dest: "{{ matrix_synapse_customized_docker_src_files_path }}/Dockerfile"
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
mode: 0640
- name: Ensure customized Docker image for Synapse is built
docker_image:
name: "{{ matrix_synapse_docker_image_customized }}"
source: build
build:
dockerfile: Dockerfile
path: "{{ matrix_synapse_customized_docker_src_files_path }}"
pull: true
- name: Check if a Synapse signing key exists - name: Check if a Synapse signing key exists
ansible.builtin.stat: ansible.builtin.stat:
path: "{{ matrix_synapse_config_dir_path }}/{{ matrix_server_fqn_matrix }}.signing.key" path: "{{ matrix_synapse_config_dir_path }}/{{ matrix_server_fqn_matrix }}.signing.key"

View file

@ -27,8 +27,11 @@
- name: Ensure Synapse Docker image doesn't exist - name: Ensure Synapse Docker image doesn't exist
docker_image: docker_image:
name: "{{ matrix_synapse_docker_image }}" name: "{{ item }}"
state: absent state: absent
with_items:
- "{{ matrix_synapse_docker_image_final }}"
- "{{ matrix_synapse_docker_image }}"
- name: Ensure sample prometheus.yml for external scraping is deleted - name: Ensure sample prometheus.yml for external scraping is deleted
ansible.builtin.file: ansible.builtin.file:

View file

@ -0,0 +1,3 @@
FROM {{ matrix_synapse_docker_image }}
{{ matrix_synapse_container_image_customizations_dockerfile_body_custom }}

View file

@ -42,7 +42,7 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name {{ matrix_synapse_wor
{% for arg in matrix_synapse_container_arguments %} {% for arg in matrix_synapse_container_arguments %}
{{ arg }} \ {{ arg }} \
{% endfor %} {% endfor %}
{{ matrix_synapse_docker_image }} \ {{ matrix_synapse_docker_image_final }} \
run -m synapse.app.{{ matrix_synapse_worker_details.app }} -c /data/homeserver.yaml -c /data/{{ matrix_synapse_worker_config_file_name }} run -m synapse.app.{{ matrix_synapse_worker_details.app }} -c /data/homeserver.yaml -c /data/{{ matrix_synapse_worker_config_file_name }}

View file

@ -60,7 +60,7 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-synapse \
{% for arg in matrix_synapse_container_arguments %} {% for arg in matrix_synapse_container_arguments %}
{{ arg }} \ {{ arg }} \
{% endfor %} {% endfor %}
{{ matrix_synapse_docker_image }} \ {{ matrix_synapse_docker_image_final }} \
run -m synapse.app.homeserver -c /data/homeserver.yaml run -m synapse.app.homeserver -c /data/homeserver.yaml
ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-synapse 2>/dev/null || true' ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-synapse 2>/dev/null || true'