This is a guide to deploying Synapse behind a Caddy reverse proxy, both running in Docker containers (an official Synapse one and a caddy-docker-proxy one), with the goal of implementing as much as possible via docker-compose files.
This guide will frequently refer to aspects of my similar guide for deploying Nextcloud behind a Caddy reverse proxy.
Obtain a domain name as per the instructions in the Nextcloud guide. For some Synapse specific considerations, see the official documentation here and here. The remainder of this guide will assume the use of the domain name example.duckdns.org
.
See the SSL section in the Nextcloud guide.
See the Docker section in the Nextcloud guide.
See the Docker network section in the Nextcloud guide.
Create the following file as something like $HOME/docker/synapse/docker-compose.yml
. It is based on this community contributed docker-compose file, modified for Caddy integration:
# based on: https://github.com/matrix-org/synapse/blob/develop/contrib/docker/docker-compose.yml
version: '3'
services:
synapse:
build:
context: ../..
dockerfile: docker/Dockerfile
image: docker.io/matrixdotorg/synapse:latest
# Since synapse does not retry to connect to the database, restart upon
# failure
restart: unless-stopped
# See the readme for a full documentation of the environment settings
# NOTE: You must edit homeserver.yaml to use postgres, it defaults to sqlite
environment:
- SYNAPSE_SERVER_NAME=example.duckdns.org
- SYNAPSE_REPORT_STATS=no
volumes:
- ./files:/data
networks:
- caddy
depends_on:
- db
# https://github.com/matrix-org/synapse/blob/develop/docker/README.md#running-synapse
# For testing, bring up the container with the following two lines
# uncommented, and try to access http://<docker_host_hostname_or_ip>:8008
#ports:
# - 8008:8008
# See https://matrix-org.github.io/synapse/latest/reverse_proxy.html
# https://matrix-org.github.io/synapse/latest/reverse_proxy.html#caddy-v2
# https://matrix-org.github.io/synapse/latest/delegate.html#well-known-delegation
# Note: delegation would normally not be required in the simple configuration
# used here, but since Duck DNS is being used for dynamic DNS service
# with wildcards, federation with matrix.org won't work without explicit delegation
# See: https://github.com/matrix-org/synapse/issues/5882
# https://github.com/matrix-org/synapse/issues/7764
# https://github.com/matrix-org/matrix-federation-tester/issues/92
labels:
caddy: (matrix-well-known-header)
caddy.header_0: Access-Control-Allow-Origin "*"
caddy.header_1: Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
caddy.header_2: Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"
caddy.header_3: Content-Type "application/json"
caddy_0: example.duckdns.org
caddy_0.reverse_proxy_0: /_matrix/* {{upstreams 8008}}
caddy_0.reverse_proxy_1: /_synapse/client/* {{upstreams 8008}}
caddy_0.handle_0: /.well-known/matrix/server
caddy_0.handle_0.import: matrix-well-known-header
caddy_0.handle_0.respond: "`{\"m.server\":\"example.duckdns.org:443\"}`"
#caddy_0.handle_1: /.well-known/matrix/client
#caddy_0.handle_0.import: matrix-well-known-header
#caddy_0.handle_0.respond: `{"m.homeserver":{"base_url":"https://matrix.example.com"},"m.identity_server":{"base_url":"https://identity.example.com"}}`
# If delegation is not required, the 'labels' section can be simplified to
# something like the following:
# labels:
# caddy_0: example.duckdns.org
# caddy_0.reverse_proxy_0: /_matrix/* {{upstreams 8008}}
# caddy_0.reverse_proxy_1: /_synapse/client/* {{upstreams 8008}}
# caddy_1: example.duckdns.org:8448
# caddy_1.reverse_proxy: "{{upstreams 8008}}"
db:
image: docker.io/postgres:12-alpine
environment:
- POSTGRES_USER=synapse
- POSTGRES_PASSWORD=<secret_password>
# ensure the database gets created correctly
# https://matrix-org.github.io/synapse/latest/postgres.html#set-up-database
- POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C
volumes:
- ./schemas:/var/lib/postgresql/data
networks:
- caddy
- external: true
Change the password to a strong random password. (It is only used internally, and will not be needed anywhere outside this file.)
As per the contributed documentation, generate a configuration file with the command (specifying SYNAPSE_SERVER_NAME and SYNAPSE_REPORT_STATS are unnecessary, since they have already been specified in the docker-compose file):
docker-compose run --rm synapse generate
Then edit the generated configuration file (at $HOME/docker/synapse/files/homeserver.yaml
), making sure it contains the following lines:
server_name: "example.duckdns.org"
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
compress: false
In $HOME/docker/synapse/
, run:
# docker-compose up -d
Set up Caddy as per the instructions in the Nextcloud guide. (If already done for the Nextcloud deployment, it does not need to be done again.)
To enable federation, Caddy should listen on port 8448 as well as port 443, so an appropriate entry should be added to the ports list in the Caddy docker-compose.yml
file (if the Caddy container is already running, restart it after modifying the file):
ports:
- 80:80
- 443:443
- 8448:8448
If everything has worked, it should be possible to access the Synapse instance from a web client, at the address https://example.duckdns.org
(without port number specification), as described in the official documentation. It is also possible to accesss the Synapse instance via a web browser, either proxied via Caddy at https://example.duckdns.org
, or directly, without going through Caddy, at http://<docker_host_hostname_or_ip>:8008
, where <docker_host_hostname_or_ip> is a hostname or IP address of the Docker host system.
To test and troubleshoot federation, the Matrix Federation Tester is useful.
Follow the official documentation to manually generate users with this command:
docker exec -it <synapse_container_name> register_new_matrix_user http://localhost:8008 -c /data/homeserver.yaml [--help]
where <synapse_container_name> is the name of the running Synapse container (e.g. synapse_synapse_1
).
(Running with the --help
switch shows the command usage and options - omit it actually to generate users.) Both admin and ordinary users can be created this way. See also the matrix-registration tool.
See the Updating section of the Nextcloud guide.