synapse post
This commit is contained in:
@@ -0,0 +1,315 @@
|
|||||||
|
---
|
||||||
|
layout: post
|
||||||
|
author: Sam Hadow
|
||||||
|
tags: messaging podman sysadmin
|
||||||
|
---
|
||||||
|
|
||||||
|
In this blog post I'll describe how to self host a [matrix.org](https://matrix.org/) instance using podman. The homeserver used will be synapse.
|
||||||
|
|
||||||
|
# What are matrix.org and synapse?
|
||||||
|
|
||||||
|
First a short introduction:
|
||||||
|
matrix.org is an open source, secure and decentralized communication protocol. Secure because it defines how end to end encryption should be implemented in the clients.
|
||||||
|
With matrix.org you have [homeservers](https://matrix.org/ecosystem/servers/) and [clients](https://matrix.org/ecosystem/clients/). Homeservers are what the clients connect to and can federate with each other *(meaning someone with an account on homeserver A can talk to someone with an account on homeserver B)*.
|
||||||
|
[Bridges](https://matrix.org/ecosystem/bridges/) to other messaging services can also be hosted alongside a homeserver. Hosting your own homeserver allows you to host the bridges you want.
|
||||||
|
In this blog post I explain how to self host a specific homeserver, which is maintained by the matrix.org foundation: synapse.
|
||||||
|
|
||||||
|
# self hosting synapse
|
||||||
|
|
||||||
|
## initial setup
|
||||||
|
|
||||||
|
### creating secret and directories
|
||||||
|
|
||||||
|
Create the database secret not to expose it in your configuration files:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo -n "<postgres-pass>" > /tmp/secret
|
||||||
|
podman secret create synapse_postgres_pass /tmp/secret
|
||||||
|
```
|
||||||
|
|
||||||
|
Adapt the path to your own path for the directories:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /home/data/podman/synapse/{db,config,media,logs}
|
||||||
|
```
|
||||||
|
|
||||||
|
### generating the configuration file
|
||||||
|
|
||||||
|
*(adapt your-domain to your own, for example: example.org)*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
podman pod create --name synapse -p 8008:8008 -m=2048m
|
||||||
|
|
||||||
|
podman run -it --rm \
|
||||||
|
-v /home/data/podman/synapse/config:/data:Z \
|
||||||
|
-e SYNAPSE_SERVER_NAME=<your-domain> \
|
||||||
|
-e SYNAPSE_REPORT_STATS=no \
|
||||||
|
docker.io/matrixdotorg/synapse:latest generate
|
||||||
|
```
|
||||||
|
|
||||||
|
### modifying the configuration file
|
||||||
|
|
||||||
|
The previous command will generate a homeserver.yaml file. You'll have to modify this file before using synapse. You'll have to modify at least the following parts:
|
||||||
|
|
||||||
|
+ modify the database part *(replace the password)*
|
||||||
|
```yaml
|
||||||
|
database:
|
||||||
|
name: psycopg2
|
||||||
|
txn_limit: 10000
|
||||||
|
args:
|
||||||
|
user: synapse
|
||||||
|
password: <POSTGRES_PASSWORD>
|
||||||
|
dbname: synapse
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 5432
|
||||||
|
cp_min: 5
|
||||||
|
cp_max: 10
|
||||||
|
```
|
||||||
|
+ set `enable_registration` to false unless you want users to register freely on your instance.
|
||||||
|
+ set a shared secret file with `registration_shared_secret_path` to have access to an [API](https://element-hq.github.io/synapse/latest/admin_api/register_api.html) to create users. Be sure to use a secure secret as anyone having this secret can register on your instance as an admin. Also keep in mind the path is relative to the container, not the host.
|
||||||
|
|
||||||
|
|
||||||
|
### reverse proxy
|
||||||
|
|
||||||
|
In this guide the port used is 8008, we'll use nginx to server the synapse homeserver on the port 443.
|
||||||
|
*(adapt your-domain to your own)*
|
||||||
|
This part is important for users to have the name user@your-domain while hosting synapse on a subdomain. And it's also important for clients and other homeserver to recognize your server.
|
||||||
|
|
||||||
|
in sites-available:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
# synapse.conf
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name synapse.<your-domain>;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/<your-domain>/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/<your-domain>/privkey.pem;
|
||||||
|
|
||||||
|
location /.well-known/matrix/server {
|
||||||
|
return 200 '{"m.server": "synapse.<your-domain>:443"}';
|
||||||
|
add_header Content-Type application/json;
|
||||||
|
}
|
||||||
|
location /.well-known/matrix/client {
|
||||||
|
return 200 '{"m.homeserver": {"base_url": "https://synapse.<your-domain>"},"m.identity_server": {"base_url": "https://vector.im"}}';
|
||||||
|
add_header Content-Type application/json;
|
||||||
|
add_header "Access-Control-Allow-Origin" *;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:8008;
|
||||||
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
|
||||||
|
# Nginx by default only allows file uploads up to 1M in size
|
||||||
|
# Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
|
||||||
|
client_max_body_size 256M;
|
||||||
|
|
||||||
|
# Synapse responses may be chunked, which is an HTTP/1.1 feature.
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In your http.conf add this snippet in the https server block:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
location /.well-known/matrix/server {
|
||||||
|
return 200 '{"m.server": "synapse.<your-domain>:443"}';
|
||||||
|
add_header Content-Type application/json;
|
||||||
|
add_header "Access-Control-Allow-Origin" *;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /.well-known/matrix/client {
|
||||||
|
return 200 '{"m.homeserver": {"base_url": "https://synapse.<your-domain>"},"m.identity_server": {"base_url": "https://vector.im"}}';
|
||||||
|
add_header Content-Type application/json;
|
||||||
|
add_header "Access-Control-Allow-Origin" *;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## running the pod
|
||||||
|
|
||||||
|
### with podman command line
|
||||||
|
|
||||||
|
Again adapt the path:
|
||||||
|
*The database version can be different but it needs to be pinned to a specific version to avoid issues with updates. You'll have to manually update this container.*
|
||||||
|
|
||||||
|
```bash
|
||||||
|
podman run -d --pod=synapse \
|
||||||
|
--secret synapse_postgres_pass,type=env,target=POSTGRES_PASSWORD \
|
||||||
|
-e POSTGRES_DB="synapse" \
|
||||||
|
-e POSTGRES_USER="synapse" \
|
||||||
|
-e POSTGRES_INITDB_ARGS="--encoding=UTF-8 --lc-collate=C --lc-ctype=C" \
|
||||||
|
-v /home/data/podman/synapse/db:/var/lib/postgresql/data:Z \
|
||||||
|
--name=synapse-db \
|
||||||
|
docker.io/library/postgres:16
|
||||||
|
|
||||||
|
podman run -d --pod=synapse \
|
||||||
|
-e SYNAPSE_CONFIG_PATH=/data/homeserver.yaml \
|
||||||
|
-v /home/data/podman/synapse/config:/data:Z \
|
||||||
|
-v /home/data/podman/synapse/media:/data/media:z \
|
||||||
|
-v /home/data/podman/synapse/logs:/data/logs:Z \
|
||||||
|
--name=synapse-app \
|
||||||
|
--label io.containers.autoupdate=registry docker.io/matrixdotorg/synapse:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can generate the systemd services:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/.config/systemd/user/
|
||||||
|
podman generate systemd --restart-policy=on-failure --files --new --name synapse
|
||||||
|
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
systemctl --user enable --now pod-synapse.service
|
||||||
|
```
|
||||||
|
|
||||||
|
### with systemd services directly
|
||||||
|
|
||||||
|
Create these files in `~/.config/systemd/user/`.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# pod-synapse.service
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Podman pod-synapse.service
|
||||||
|
Documentation=man:podman-generate-systemd(1)
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
RequiresMountsFor=/run/user/1000/containers
|
||||||
|
Wants=container-synapse-app.service container-synapse-db.service
|
||||||
|
Before=container-synapse-app.service container-synapse-db.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||||
|
Restart=on-failure
|
||||||
|
TimeoutStopSec=70
|
||||||
|
ExecStartPre=/usr/bin/podman pod create \
|
||||||
|
--infra-conmon-pidfile %t/pod-synapse.pid \
|
||||||
|
--pod-id-file %t/pod-synapse.pod-id \
|
||||||
|
--exit-policy=stop \
|
||||||
|
--name synapse \
|
||||||
|
-p 8008:8008 \
|
||||||
|
-m=2048m \
|
||||||
|
--replace
|
||||||
|
ExecStart=/usr/bin/podman pod start \
|
||||||
|
--pod-id-file %t/pod-synapse.pod-id
|
||||||
|
ExecStop=/usr/bin/podman pod stop \
|
||||||
|
--ignore \
|
||||||
|
--pod-id-file %t/pod-synapse.pod-id \
|
||||||
|
-t 10
|
||||||
|
ExecStopPost=/usr/bin/podman pod rm \
|
||||||
|
--ignore \
|
||||||
|
-f \
|
||||||
|
--pod-id-file %t/pod-synapse.pod-id
|
||||||
|
PIDFile=%t/pod-synapse.pid
|
||||||
|
Type=forking
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# container-synapse-db.service
|
||||||
|
[Unit]
|
||||||
|
Description=Podman container-synapse-db.service
|
||||||
|
Documentation=man:podman-generate-systemd(1)
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
RequiresMountsFor=%t/containers
|
||||||
|
BindsTo=pod-synapse.service
|
||||||
|
After=pod-synapse.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||||
|
Restart=on-failure
|
||||||
|
TimeoutStopSec=70
|
||||||
|
ExecStart=/usr/bin/podman run \
|
||||||
|
--cidfile=%t/%n.ctr-id \
|
||||||
|
--cgroups=no-conmon \
|
||||||
|
--rm \
|
||||||
|
--pod-id-file %t/pod-synapse.pod-id \
|
||||||
|
--sdnotify=conmon \
|
||||||
|
--replace \
|
||||||
|
-d \
|
||||||
|
--secret synapse_postgres_pass,type=env,target=POSTGRES_PASSWORD \
|
||||||
|
-e POSTGRES_DB=synapse \
|
||||||
|
-e POSTGRES_USER=synapse \
|
||||||
|
-e "POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C" \
|
||||||
|
-v /home/data/podman/synapse/db:/var/lib/postgresql/data:Z \
|
||||||
|
--name=synapse-db \
|
||||||
|
docker.io/library/postgres:16
|
||||||
|
ExecStop=/usr/bin/podman stop \
|
||||||
|
--ignore -t 10 \
|
||||||
|
--cidfile=%t/%n.ctr-id
|
||||||
|
ExecStopPost=/usr/bin/podman rm \
|
||||||
|
-f \
|
||||||
|
--ignore -t 10 \
|
||||||
|
--cidfile=%t/%n.ctr-id
|
||||||
|
Type=notify
|
||||||
|
NotifyAccess=all
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# container-synapse-app.service
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Podman container-synapse-app.service
|
||||||
|
Documentation=man:podman-generate-systemd(1)
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
RequiresMountsFor=%t/containers
|
||||||
|
BindsTo=pod-synapse.service
|
||||||
|
After=pod-synapse.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||||
|
Restart=on-failure
|
||||||
|
TimeoutStopSec=70
|
||||||
|
ExecStart=/usr/bin/podman run \
|
||||||
|
--cidfile=%t/%n.ctr-id \
|
||||||
|
--cgroups=no-conmon \
|
||||||
|
--rm \
|
||||||
|
--pod-id-file %t/pod-synapse.pod-id \
|
||||||
|
--sdnotify=conmon \
|
||||||
|
--replace \
|
||||||
|
-d \
|
||||||
|
-e SYNAPSE_CONFIG_PATH=/data/homeserver.yaml \
|
||||||
|
-v /home/data/podman/synapse/config:/data:Z \
|
||||||
|
-v /home/data/podman/synapse/media:/data/media:z \
|
||||||
|
-v /home/data/podman/synapse/logs:/data/logs:Z \
|
||||||
|
--name=synapse-app \
|
||||||
|
--label io.containers.autoupdate=registry docker.io/matrixdotorg/synapse:latest
|
||||||
|
ExecStop=/usr/bin/podman stop \
|
||||||
|
--ignore -t 10 \
|
||||||
|
--cidfile=%t/%n.ctr-id
|
||||||
|
ExecStopPost=/usr/bin/podman rm \
|
||||||
|
-f \
|
||||||
|
--ignore -t 10 \
|
||||||
|
--cidfile=%t/%n.ctr-id
|
||||||
|
Type=notify
|
||||||
|
NotifyAccess=all
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
|
```
|
||||||
|
|
||||||
|
## managing the homeserver
|
||||||
|
|
||||||
|
### registering users
|
||||||
|
|
||||||
|
With access to the server, creating the user interactively:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
podman exec -it synapse-app /bin/sh
|
||||||
|
register_new_matrix_user --user <username> --config /data/homeserver.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Or with the registration API, you can use [this script](https://git.hadow.fr/sam.hadow/Useful-scripts/src/branch/main/create_matrix_account.sh).
|
||||||
Reference in New Issue
Block a user