Skip to content

Instantly share code, notes, and snippets.

@faaaaabi
Last active October 10, 2024 16:48
Show Gist options
  • Save faaaaabi/8042e816f3198e43c611f2a2dcab051c to your computer and use it in GitHub Desktop.
Save faaaaabi/8042e816f3198e43c611f2a2dcab051c to your computer and use it in GitHub Desktop.
A basic setup for synapse with postgres behind a nginx reverse proxy

Synapse Docker Compose Setup

This proposed setup assumes that you want to use synapse with a Postgres database behind a separate nginx reverse proxy for TLS.

Setup

DNS setup

A detailed explanation of a basic and extended dns setup can be found here

Generate synapse config

Change the environment variable SYNAPSE_SERVER_NAME to your desired domain

docker run -it --rm \
    -v $PWD/synapse-data:/data \
    -e SYNAPSE_SERVER_NAME=my.matrix.host \
    -e SYNAPSE_REPORT_STATS=no \
    matrixdotorg/synapse:latest generate

This will generate the folder synapse-data in your current working directory. The file of most importance for the setup in this folder is the file homeserver.yaml

Configuring Postgres with Synapse

Comment the sqlite3 block in your homeserver.yaml and uncomment the database block with the value psycopg2 for the key name. An exemplary block could look like this:

database:
  name: psycopg2
  args:
    user: synapse
    password: SuperSecretPassword
    database: synapse
    host: db # The service name defined in your docker-compose file
    cp_min: 5
    cp_max: 10

One configuration value you should also know of, is enable_registration. Its default value is true. Set it to false if you don't want anybody to be able to register a user on your homeserver. For your homeserver to be able to send emails (e.g. for notifications or password resets, you have to provide smtp credentials in the email block of your homeserver.yaml)


Setup a docker-compose file

An exemplary docker-compose file could look like this:

version: '3'

services:

  synapse:
    image: docker.io/matrixdotorg/synapse:latest
    restart: unless-stopped
    volumes:
      - ./synapse-data:/data
    depends_on:
      - db
    ports:
      - '127.0.0.1:8008:8008/tcp'
  db:
    image: docker.io/postgres:latest
    restart: unless-stopped
    environment:
      - POSTGRES_USER=synapse
      - POSTGRES_PASSWORD=SuperSecretPassword
      - POSTGRES_INITDB_ARGS=--encoding='UTF8' --lc-collate='C' --lc-ctype='C'
    volumes:
      - ./postgres-data:/var/lib/postgresql/data

The username, password and service-name you chose here, must correspond with the settings for user, password and host of the aforementioned database block in your homeserver.yaml. Chose a port-mapping that is the most suitable for your environment. It could be a good idea to tie the version of the synapse and postgres docker images to a specific version. If you want to so, exchange latest with your desired version.

Start your setup

To start your setup in the detached mode execute the following. Otherwise execute it without the -d option

docker-dompose up -d

Setup a nginx reverse proxy

server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name your.matrix.tld;
        ssl_certificate /etc/letsencrypt/live/some.domain.tld/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/some.domain.tld/privkey.pem; # managed by Certbot

        client_max_body_size 50M;

        location / {
            proxy_pass http://localhost:8008;
            proxy_set_header X-Forwarded-For $remote_addr;
        }

        location /.well-known/matrix/ {
          root /opt/docker/synapse-fabi-dev/nginx/www/;
          default_type application/json;
          add_header Access-Control-Allow-Origin  *;
        }

}

server {
        listen 8448 ssl default_server;
        listen [::]:8448 ssl default_server;
        server_name your.matrix.tld;
        ssl_certificate /etc/letsencrypt/live/some.domain.tld/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/some.domain.tld/privkey.pem; # managed by Certbot

        client_max_body_size 50M;

        location / {
            proxy_pass http://localhost:8008;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
}

Change the proxy_pass values to your chosen port. Change the values for server_name to your chosen (sub-)domain. Provide a valid certificate and key for ssl_certificate and ssl_certificate_key. This setup is assumes that you will get your certs via letsencrypt's certbot. The /.well-known/matrix/ block is only necessary if yo want to provide your clients specific configuration parameters (eg. which integration-manager or jitsi instance to use) and can otherwise be commented or deleted. See this link for further information about the files in ./well-known/matrix/

The second server block provides synapse also via port 8448, as needed by the matrix standard for server<->server communication. Without that, federation would not work

Change the value of client_max_body_size to your needs. You also have to edit the vlaue for max_upload_size in your homeserver.yaml

Upgrade your synapse version

If you use the latest tag for your synapse docker image, simply simply execute docker-compose pull synapse && docker-compose up -d. Keep in mind that upgrades to a new major version might not work, depending on your last version. See the synapse docs for further information. If you tied the synapse docker image to a specific version, simply change the version tag to your desired version and execute the same docker-compose commands as above.

@Haui1112
Copy link

This is an awesome guide! Worked nearly first try. (I'd probably add that if you make a mistake with postgresql, you need to delete the database since the password is stored even if you change it later)

One thing doesnt work for me though: I cant register on my server and the documentation of synapse is very hard to understand.

Have a good one!

@JSchmie
Copy link

JSchmie commented Sep 29, 2024

Hi,

Thank you for this guide – it was incredibly helpful! I just wanted to provide a quick update for 2024, specifically regarding the use of Nginx Proxy Manager.

I needed to modify the port forwarding settings for the Synapse container from 127.0.0.1:8008:8008/tcp to simply 8008:8008/tcp or 8008:8008, as the latest version of the container now listens on 0.0.0.0.

Below is an updated Compose file that worked for me using Portainer:

name: synapse
services:
  synapse:
    container_name: synapse
    image: docker.io/matrixdotorg/synapse:latest
    restart: unless-stopped
    volumes:
      - /compose_data/synapse/synapse-data:/data
    depends_on:
      - synapse-db
    ports:
      - 8008:8008/tcp
  synapse-db:
    container_name: synapse-db
    image: docker.io/postgres:latest
    restart: unless-stopped
    environment:
      - POSTGRES_USER=synapse
      - POSTGRES_PASSWORD=$POSTGRES_PASSWORD
      - POSTGRES_INITDB_ARGS=--encoding='UTF8' --lc-collate='C' --lc-ctype='C'
    volumes:
      - /compose_data/synapse/postgres-data:/var/lib/postgresql/data

Here $POSTGRES_PASSWORD can be set in the Portainer UI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment