For those of us looking to move away from centralized messaging services such as WhatsApp, hosting our own versions is attractive. Enter Synapse/Matrix, and a whole host of ready-made clients you can use, safe in the knowledge that your messages aren't going anywhere except between you and your contacts.
docker-compose up -dor
docker runand everything works out nicely. That being said, it's not the most complicated of processes, so you should find the below steps relatively easy to follow
- Docker and docker-compose installed on your machine
- sudo privileges to be able to run docker commands as root, or you've added your user to the docker group to bypass that
- The ability to SSH / use CLI/terminal on your machine, or use Portainer to spin up your stacks
- Some sort of access and relevant permissions to manage and create new directories
- If you intend to use federation, an FQDN (fully qualified domain name) such as
- A reverse proxy already set up for the service you want, on its own docker network (for instance called
proxy) with the relevant SSL certificate(s) (check out my SWAG article for some info on how to do that if you haven't already)
Setting up Synapse
There are a number of steps here.
Choosing your Synapse server name
This needs to be done first, as it cannot be changed later.
Any users who join your server will be reachable at
@user:server-name.example. If you are planning on having your instance completely separate and private from the web (i.e. you cannot join other Synapse selfhosted instances and they cannot see yours) then this server name can be anything you want.
If however you do want to be able to join other servers, then you need federation (click the link to read more about it) and that means using your FQDN, such as
pointtosource.com, with a reverse proxy, such as SWAG.
I will choose my server name to be
element.pointtosource.com which means that I, with the username
PTS would have be reachable at
Creating your folder structure
For this project we need a few folders to be set up.
- Navigate to your
dockerfolder, or wherever you keep your compose files, and create a new
- Inside your
synapsefolder, create two files,
- Still inside your
synapsedirectory, create two folders,
Creating your proxy docker network
The compose file below will create a
synapse docker bridge network for you but relies on a pre-existing proxy network for your reverse proxy. I'm assuming you have one already, but if not, here's how to create it:
- SSH into your machine
- Copy and paste the following:
docker network create proxy
Creating your docker-compose and .env files
Create and edit a
docker-compose.yml file, pasting in the contents below:
networks: default: name: synapse proxy: # reverse proxy network, edit as necessary external: true 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 container_name: synapse environment: - SYNAPSE_CONFIG_PATH=/data/homeserver.yaml volumes: - ./config:/data depends_on: - synapse-db ports: - 8448:8448/tcp networks: - default - proxy synapse-db: image: docker.io/postgres:12-alpine container_name: synapse-db environment: - POSTGRES_USER=$PGUSR - POSTGRES_PASSWORD=$PGPWD - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C volumes: - ./schema:/var/lib/postgresql/data
- Create and edit a
.envfile, pasting the contents below:
PGPWD=[create a strong password here] PGUSR=[create your username here]
Once you've saved the above 2 files, you can move onto the next step.
Generating your config file
Once you have chosen your server name, you need to create a few folders.
- Inside your preferred
dockerfolder, create a subfolder tree
configis a folder inside
- SSH into your machine
- Copy the following command
When you've done that, you should get an output similar to below. Note the files on the left hand side of the image which have been created, notably the
There are a LOT of config options for the
homeserver.yaml file which I recommend you read here. However we need to make a few changes ourselves, namely to enable registration and also set the database to the postgres one we just created.
Editing the homserver config file
As mentioned above, a few things for us to do here:
Enabling user registration with a captcha
- Visit this page which walks you through setting up a catcha site
- Make sure you save your public key and secret keys
- Open your
- Scroll to the bottom and add the following lines
- In your
homserver.yamlfile, locate the part that starts with
databasesand looks like this:
database: name: sqlite3 args: database: /data/homeserver.db
- Paste over the above by copying the following lines:
database: name: psycopg2 args: user: [the USER you specified in the .env file] password: [the PASSWORD you specified in the .env file] database: postgres host: synapse-db cp_min: 5 cp_max: 10
Save the file.
At this point, I recommend setting up your reverse proxy to point to
Spinning up the containers
You can now spin up the full stack, by typing
docker-compose up -d into your SSH client while in the
synapse folder. All being well, you will get a number of lines in the logs with no errors.
Testing and using your synapse instance
The best way to do this is to download the
Element client on your device, or in your browser go directly to
- Click the 'Edit' button top right
- Select 'Other homeserver' and type in the URL (not server name you chose earlier), then press 'Continue'
- Select a username (all lowercase) and your passwords, then press 'Continue'
- Your captcha should then pop up, tick the 'I am not a robot' button and then follow the captcha
And you're in!
Additional clients for the same user
Once you've created an account, every time you log in using a different client you will need to verify it using an existing account. For example, if you download Element for Android and now log in, you will need to verify it on element web.
Setting a user as an admin
For this, we need to bash into our postgres container and edit it directly:
- Paste the following into your SSH terminal:
docker exec -it synapse-db bash psql postgres [username] UPDATE users SET admin = 1 WHERE name = '@user:your.synapse.server';
[username]with the USER you set in your
@user:your.synapse.serverwith the user you just registered, i.e.
- When you've run those three, you should get an output of
You can now find your access token using Element in your browser. This is necessary when making admin level API requests on your Synapse host machine.
- Log in again (if necessary)
- Click the settings cog bottom left, then click the 'All settings' button
- Click 'Help & About' in the left hand nav panel
- Scroll to the bottom of the modal and then hit the drop down arrow for 'Access Token'
When all your users are added, you can comment out the
enable users line in the
homeserver.yaml and restart the container. This prevents others you don't know from being able to register.
Alternatively, you could set
registration_requires_token and manage it that way, wherein only users with the correct tokens can register. This requires more admin management, and you can read up more on that here.
And that's it. You now have your very own Synapse server which works with Element!