General Information
This guide helps to install Synapse
Matrix Server, Riot
Web UI, coturn
Turn Server, Dimension
integration server, jitsi
conferencing system and the matrix user/room admin
tool. It assumes there is an apache
web-server serving requests from the outside world.
None of the components or the information is originally mine. This is just an attempt to summarize all together in a long how-to.
Note 1: I will be installing all the docker packages at
/home/*
Note 2:
server.key
,server.crt
andca.crt
are respectively private key, public key, and certificate-authority certificate to be used by components. I usually have a wildcard certificate for all my subdomains. but if you don’t want to use such a certificate, then you need separate certificates when creating reverse-proxies or configuring your turn-server
Before we begin
You can consider installing portainer
to ease the management of dockers. Unfortunately, the docker-compose files cannot be used directly in portainer
, as it doesn’t support version: '3'
and above. Nevertheless, it provides a nice UI to see the status of each container, to manage it, and to check out the logs.
This could (probably) be used to install portainer
container. It will start a web-UI on port 9000
of the docker machine, through which it’s possible to restart, recreate, and modify containers, as well as defining new containers, seeing log files and performance statistics etc.
- Installation path:
/home/portainer
- Don’t forget to map
docker.sock
to/var/run/docker.sock
- Ports:
9000
for UI
Note: Please consider security factors when exposing this container to the internet, as any person with administrative right can install and modify your containers.
version: '3' services: portainer: image: portainer/portainer container_name: portainer restart: always command: -H unix:///var/run/docker.sock ports: - "9000:9000" volumes: - /var/run/docker.sock:/var/run/docker.sock - /home/portainer/data:/data - /home/portainer/shared:/shared environment: - TZ=${TZ}
Configure Turn Server
Let’s start with coturn
TURN-Server. it’s independent of other components and can be used for several different purposes.
You can read more about the functionality of TURN and STUN servers here: https://blog.ivrpowers.com/post/technologies/what-is-stun-turn-server/
- Original Documentation: https://github.com/instrumentisto/coturn-docker-image
- Installation Path:
/home/coturn
- needed ports:
3478
,5349
,49100-49200
- docker image:
instrumentisto/coturn
network_mode
is set tohost
in order to ease the mapping of ports from the container to the outside world.- Configuration files are stored in
{installation-path}/conf
- SSL keys and certificates are to be stored in
{installation-path}/keys
docker-compose.yml
as provided
#/home/coturn/docker-compose.yml version: '3' services: coturn: restart: unless-stopped container_name: coturn image: instrumentisto/coturn network_mode: host volumes: - /home/coturn/conf:/etc/coturn/ - /home/coturn/keys:/data/keys/ - /home/coturn/log:/data/log/
data/turnserver.conf
as provided- define
your-domain.com
static-auth-secret
can be any string. I’d recommend selecting a fully randomized hash with a length of at least 32 to ensure security. OpenSSL can be used to create a random value:openssl rand -hex 64
oropenssl rand -base64 64
- define the external-IP to point to your public IP if the server is behind NAT
listening-port
,tls-listening-port
andmin|max-port
must be opened on outwards facing firewall
- define
#/home/coturn/data/turnserver.conf listening-port=3478 tls-listening-port=5349 external-ip=<public-ip>[/<private-ip>] #defines a mapping between public and private IPs min-port=49100 max-port=49200 fingerprint use-auth-secret static-auth-secret=<create-your-own> realm=<your-domain.com> user-quota=12 total-quota=1200 max-bps=4096000 no-tcp-relay stale-nonce=600 cert=/data/keys/server.crt pkey=/data/keys/server.key CA-file=/data/keys/ca.crt cipher-list="ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AES:RSA+3DES:!ADH:!AECDH:!MD5" no-tlsv1 no-tlsv1_1 no-sslv3 log-file=/data/log/turn.log no-multicast-peers #user=username;password
- To test the server, you can use https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ with
turn:<your-domain.com>:<listening_port>
using user information which can be defined as hardcoded values inturnserver.conf
(user=username;password
)please comment the hardcoded user after the test and restart the server - A complete
turnserver.conf
can be found at https://github.com/coturn/coturn/blob/master/examples/etc/turnserver.conf
Matrix-Synapse
Configuring Home-Server
Based on the documentation provided in https://github.com/matrix-org/synapse/blob/master/docker/README.md, it’s a relatively straight-forward job to install the docker container.
- Installation path:
/home/synapse
- the
/home/synapse/data
folder must be writable by the container. Usually the991:991
user:group combination needs to have write-permissions. If this is not guaranteed, the creation ofhomeserver.db
(the database created by the internalsqlite
db) will fail and matrix fails to start properly.
- the
- The first step is to create a new sample
homeserver.yaml
file using following command.<your-domain.com>
is the domain name of your matrix server, and also will be the suffix for your users (@username:<your-domain.com>
).
docker run -it --rm -v/home/synapse/data:/data \ -e SYNAPSE_SERVER_NAME=<your-domain.com> \ -e SYNAPSE_REPORT_STATS=yes \ matrixdotorg/synapse:latest generate
- Following changes are necessary in order to configure the
homeserver
.openid
resource is used bydimension
integration server. It should be added to thelisteners.resources.names
.- Provided config causes the server to listen for
http
connections on port8008
. public_baseurl
MUST not be the same as yourserver_name
, but it would make things easier, as thesynapse
server provides a minimum/.well-known/matrix
path.turn_uris
(their URL and port) andturn_shared_secret
must be set according to the configuration of the turn-server.- It’s possible to configure an email server for synapse, in order to allow it to send emails on registrations or other events.
client_base_url
can point to theriot
web-client.
#/home/synapse/data/homeserver.yaml server_name: "<your-domain.com>" pid_file: /data/homeserver.pid public_baseurl: https://<your-domain.com>/ listeners: - port: 8008 tls: false type: http x_forwarded: true resources: - names: [client, federation,openid] compress: false turn_uris: ["turns:<your-turnserver.com>:5349?transport=udp", "turns:<your-turnserver.com>:5349?transport=tcp", "turn:<your-turnserver.com>:3478?transport=udp", "turn:<your-turnserver.com>:3478?transport=tcp"] turn_shared_secret: "<your-static-auth-secret-from-turnserver>" email: smtp_host: <your-mail-server.com> smtp_port: <smtp-port> smtp_user: "<smtp-user>" smtp_pass: "<smtp-pass>" # require_transport_security: true notif_from: "Your Server's Name <your-address@your-domain.com>" app_name: "Your Application Name" enable_notifs: false client_base_url: "<your-riot-url>" validation_token_lifetime: 15m
- docker-compose can be as followed:
services: synapse: image: matrixdotorg/synapse:latest restart: unless-stopped container_name: matrix-synapse environment: - SYNAPSE_CONFIG_PATH=/data/homeserver.yaml volumes: # You may either store all the files in a local folder - /home/synapse/data:/data # .. or you may split this between different storage points # - ./files:/data # - /path/to/ssd:/data/uploads # - /path/to/large_hdd:/data/media ports: - 8008:8008/tcp #depends_on: # - syanpse-db
Note: It’s possible to use an external database instead of the internal
sqlite
delivered with the image. It’s possible to use external (also docker container) databases. Please check https://github.com/matrix-org/synapse#using-postgresql and https://github.com/matrix-org/synapse/blob/master/docs/postgres.md for more info and an example on how to use PostgreSQL.
Configuring Synapse Reverse Proxy
Next step is to configure the reverse proxy
for synapse
server. for detailed info, please visit https://github.com/matrix-org/synapse#using-a-reverse-proxy-with-synapse.
In this guide, the federation port will be the same as the client connection port. Therefore, it’s not necessary to configure the port 8448
. In addition to the /_matrix
path, there is a reverse-proxy configured for /_synapse
which can be used by synapse-admin
or other tools to manage the users and other properties of synapse
.
- Don’t forget to replace
<synapse-internal-ip>
with the IP address of the docker-machine. - This config assumes that the
http
listener is running on port8008
of thesynapse
server. - It also ensures that the
_matrix
and_synapse
resources are not cached by browsers. - The first
VirtualHost
is there to redirect allhttp
requests tohttps
.
<VirtualHost *:80> ServerName <your-domain.com> <IfModule rewrite_module> RewriteEngine on RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L] </IfModule> </VirtualHost> <VirtualHost *:443> ServerName <your-domain.com>; AllowEncodedSlashes NoDecode ProxyPass /_matrix http://<synapse-internal-ip>:8008/_matrix nocanon ProxyPassReverse /_matrix http://<synapse-internal-ip>:8008/_matrix ProxyPass /_synapse http://<synapse-internal-ip>:8008/_synapse nocanon ProxyPassReverse /_synapse http://<synapse-internal-ip>:8008/_synapse <LocationMatch "^/(_matrix|_synapse)"> <IfModule mod_headers.c> Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" Header set Pragma "no-cache" </IfModule> </LocationMatch> SSLEngine On SSLCertificateFile "</path/to/server.crt>" SSLCertificateKeyFile "</path/to/server.key>" SSLCertificateChainFile "</path/to/ca.crt>" </VirtualHost>
Creating a new user – Main Admin Account
After configuring the synapse
server, it’s necessary to create at least one admin user, in order to be able to use the synapse admin
tool. To do so, please use docker exec -it matrix-synapse register_new_matrix_user -c /data/homeserver.yaml https://<server_name>
and follow the instructions. Type ‘yes’ if you want to create an admin user. Please note:
matrix-synapse
is the name assigned to thesynapse
server usingcontainer_name
in respectivedocker-compose.yml
. The name might vary if you have not used that config.<server_name>
should be the same as in yourhomeserver.yaml
./data/homeserver.yaml
might need to be adjusted according to your configurations.
for more information, please visit https://github.com/matrix-org/synapse/blob/master/INSTALL.md#registering-a-user.
Providing .well-known
Service Discovery
Synapse
server automatically provides minimal discovery data via /.well-known/matrix/client file. But this might not be enough depending on the needs.
One way to provide this information is to manually create and manage JSON files under /.well-known/matrix/{client|server}
files.
To do so:
- create the path
/.well-known/matrix
on web-server - create the
.htaccess
file and make sure the web-server is set to consider it..htaccess
is needed to ensure properCORS
headers onclient
andserver
files, without which the web-clients and other servers won’t be able to use the discovery information.- following headers can be set in
.htaccess
#/.well-known/matrix/.htaccess Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"
- create
/.well-known/matrix/client
with the following contents. this defines where the clients should look for client-server communication withsynapse
server.
{ "m.homeserver": { "base_url": "https://<server_name>" } }
- if a local
jitsi
server is to be used by clients while trying to create conference calls, please add following config to theclient
file as a new JSON property. Please remember, that the<your-jitsi-domain>
doesn’t need thehttps://
prefix.
"im.vector.riot.jitsi":{ "preferredDomain": "<your-jitsi-domain>" }
- Create
/.well-known/matrix/server
with following contents. this defines the federation information for other servers. if this is not defined, other servers use port8448
per default to get information when federating, which has not been enabled by the configuration provided here. It’s also only needed to some extent, as thesynapse
server is already behind ourhttps
enabled reverse-proxy.
{ "m.server": "<server_name>:443" }
More information on
.well-known
server discovery can be found in https://matrix.org/docs/spec/client_server/latest#well-known-uri.More Information on necessary
CORS
headers formatrix
can be found in https://matrix.org/docs/spec/client_server/latest#cors.More information on federation delegation and server-server connections can be found in https://github.com/matrix-org/synapse/blob/master/docs/delegate.md.
Installing Synapse-Admin
In order to ease matrix user management, I’d recommend using awesometechnologies/synapse-admin
. It’s really easy to install and use.
Note 1: Please do not deactivate users. It’s not possible to reactivate them.
Note 2: Please be careful when exposing this sub-system to the internet. if your admin password is leaked or cracked, then your matrix server can be compromised.
{installation_path}
:/home/synapse-admin
- Ports: 8001 for
http
requests synapse-admin
can be found in https://github.com/Awesome-Technologies/synapse-admin.
#/home/synapse-admin/docker-compose.yml version: '3' services: synapse-admin: image: awesometechnologies/synapse-admin container_name: synapse-admin ports: - 8001:80
Dimension
Integration Server
Installation
Integration servers provide extra services to matrix users. You can read more about integration server for example in https://github.com/turt2live/matrix-dimension.
At the moment, only
riot
web and desktop can use the services fromdimension
integration server.
The instructions on the website are pretty good, but a summary here:
- Installation path:
/home/dimension
- The
/home/dimension/data
folder should be writable from the docker. if the container cannot start, please check the logs to see if the/data/bot.json
file is writable; that might be the cause behind the issue.
- The
- Ports:
8184
forhttp
requests from clients - Before starting the container, create the
config.yaml
file.- Create a user for dimension on matrix server. Its token is needed for configuration of
dimension
. To obtain the token, login with the user using riot-desktop client, click on the user, go toSettings > Help & About
and scroll to theAdvanced
section. TheAccess Token
can be found there. The token must be provided inaccessToken
as<dimension-user-token>
. homeserver.name
is the your matrix’server_name
.homeserver.clientServerUrl
is the same as defined in.well-known
service discovery’shomeserver.base_url
.dimension.baseUrl
(<your-dimension-domain.com>
) is the (sub-)domain, on which yourdimension
server is accessible. something likedimension.<your-domain.com>
…admins
is a list of users with administrative rights inmatrix-synapse
who are allowed to configure and add integration services.web
parameters can be left as they are, as there will be a reverse proxy entry for this server’s access over the internet.
- Create a user for dimension on matrix server. Its token is needed for configuration of
#/home/dimension/docker-compose.yml version: "3" services: dimension: container_name: 'dimension' image: turt2live/matrix-dimension ports: - 8184:8184 volumes: - /home/dimension/data/:/data/
#/home/dimension/data/config.yaml web: port: 8184 address: '0.0.0.0' homeserver: name: "<your-domain.com>" clientServerUrl: "https://<your-domain.com>" accessToken: "<dimension-user-token>" admins: - "<matrix-admin-user>" widgetBlacklist: - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16 - 127.0.0.0/8 database: file: "/data/dimension.db" botData: "/data/bot.json" goneb: avatars: giphy: "mxc://t2bot.io/c5eaab3ef0133c1a61d3c849026deb27" imgur: "mxc://t2bot.io/6749eaf2b302bb2188ae931b2eeb1513" github: "mxc://t2bot.io/905b64b3cd8e2347f91a60c5eb0832e1" wikipedia: "mxc://t2bot.io/7edfb54e9ad9e13fec0df22636feedf1" travisci: "mxc://t2bot.io/7f4703126906fab8bb27df34a17707a8" rss: "mxc://t2bot.io/aace4fcbd045f30afc1b4e5f0928f2f3" google: "mxc://t2bot.io/636ad10742b66c4729bf89881a505142" guggy: "mxc://t2bot.io/e7ef0ed0ba651aaf907655704f9a7526" echo: "mxc://t2bot.io/3407ff2db96b4e954fcbf2c6c0415a13" circleci: "mxc://t2bot.io/cf7d875845a82a6b21f5f66de78f6bee" jira: "mxc://t2bot.io/f4a38ebcc4280ba5b950163ca3e7c329" stickers: enabled: true stickerBot: "@stickers:t2bot.io" managerUrl: "https://stickers.t2bot.io" dimension: publicUrl: "https://<your-dimension-domain.com>" logging: file: /data/logs/dimension.log console: true consoleLevel: info fileLevel: verbose rotate: size: 52428800 # bytes, default is 50mb count: 5
Reverse proxy for dimension
- define following
virtual-host
in APACHE.- The
<dimension-internal-ip>
is the IP address of the Docker server, on which the dimension server is installed. - Port
8148
is the same as inconfig.yaml
mention in the installation guide above. <your-dimension-domain.com>
is also defined in the last step.
- The
- After restarting APACHE, check the configuration by visiting
https://<your-dimension-domain.com>
. There should be a page defining how to configureriot web-ui
. - The first
VirtualHost
ensures that all traffic goes overHTTPS
.
<VirtualHost *:80> ServerName <your-dimension-domain.com> <IfModule rewrite_module> RewriteEngine on RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L] </IfModule> </VirtualHost> <VirtualHost *:443> SSLEngine on ServerName <your-dimension-domain.com>; ProxyPass / http://<dimension-internal-ip>:8148/ ProxyPassReverse / http://<dimension-internal-ip>:8148/ ProxyRequests On SSLEngine On SSLCertificateFile "</path/to/server.crt>" SSLCertificateKeyFile "</path/to/server.key>" SSLCertificateChainFile "</path/to/ca.crt>" </VirtualHost>
Riot
Web Client
Installation
The https://riot.im/app/
web-application can work with a self-hosted server as long as the server is available over the internet. but it’s not that “nice” to provide that link to customers or even friends as it might cause some confusion when trying to configure the home-server
and other features.
It’s possible to use a self-hosted version of riot web-ui
to customize the feeling. This can be done using following guide or by reading the configuration reference in https://github.com/vector-im/riot-web/blob/develop/docs/config.md:
- Installation path:
/home/riot/
- Ports:
8080
forhttp
connections - Mapping
/app/themes/<your-theme>
is not necessary, but if you want to customize the experience, like adding your own logo and background, it’s easier to manage this folder. For more information on customization, please check the config-reference, the part withbranding
. - Either create an empty
/home/riot/data/config.json
or copy the example from https://riot.im/develop/config.json and start modifying/adding the configurations you want.- a minimal/ optimal example can be found here below.
#/home/riot/docker-compose.yml version: '3' services: riot-ui: image: vectorim/riot-web container_name: riot-ui restart: unless-stopped volumes: - /home/riot/data/config.json:/app/config.json - /home/riot/data/themes/<your-theme>/:/app/themes/<your-theme> ports: - 8080:80
- A complete list of configuration and their functionality can be found in the configuration reference mentioned above. My minimal
config.json
is as follows.- if you don’t have your own
jitsi
server, you can omit thejitsi
config part. In that case,riot
usesjitsi.riot.im
when creating conference rooms. - you need to define
<your-riot-domain.com>
, which is going to be used below when creating the reverse-proxy. - if you want to have your permalinks and share links to be served from your own domain, please set
permalinkPrefix
to<your-riot-domain.com>
, otherwise you can use the default value (which points to matrix.to) by omitting the option.
- if you don’t have your own
{ "default_server_name": "<your-domain.com>", "piwik":false, "brand": "<your riot's name - appearing in title bar>", "disable_guests":true, "default_federate": false, "disable_custom_urls":true, "branding":{ "authHeaderLogoUrl":"/themes/<your-theme>/<your-logo>", "welcomeBackgroundUrl":[ "/themes/<your-theme>/<your 1st bg>", "/themes/<your-theme>/<your 2nd bg>", ... ] }, "integrations_ui_url": "https://<your-dimension-domain.com>/riot", "integrations_rest_url": "https://<your-dimension-domain.com>/api/v1/scalar", "integrations_widgets_urls": [ "https://<your-dimension-domain.com>/widgets" ], "integrations_jitsi_widget_url":"https://<your-dimension-domain.com>/widgets/jitsi", "hosting_signup_link": "", "bug_report_endpoint_url": "https://riot.im/bugreports/submit", "features": { "feature_pinning": "labs", "feature_custom_status": "labs", "feature_custom_tags": "labs", "feature_state_counters": "labs", "feature_many_integration_managers": "labs", "feature_mjolnir": "labs", "feature_dm_verification": "labs", "feature_cross_signing": "enable", "feature_invite_only_padlocks": "enable", "feature_event_indexing": "disable", "feature_bridge_state": "labs", "feature_presence_in_room_list": "labs", "feature_custom_themes": "labs" }, "roomDirectory": { "servers": [ "<your-domain.com>" ] }, "enable_presence_by_hs_url": { "https://<your-domain.com>": true }, "jitsi":{ "prefferedDomain":"<your-jitsi-domain.com-without-https>" }, "permalinkPrefix":"https://<your-riot-domain.com>", "terms_and_conditions_links": [ { "url": "https://riot.im/privacy", "text": "Privacy Policy" }, { "url": "https://matrix.org/legal/riot-im-cookie-policy", "text": "Cookie Policy" } ] }
Reverse Proxy
- as always, I’ll assume the port on which
riot
runs is the same as in provided configuration (i.e.8080
) <riot-internal-ip>
should be the IP address of the docker machine.riot
will be accessible on<your-riot-domain.com>
/- Again, the first
VirtualHost
is there to redirect all your traffic overhttps
.
<VirtualHost *:80> ServerName <your-riot-domain.com> <IfModule rewrite_module> RewriteEngine on RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L] </IfModule> </VirtualHost> <VirtualHost *:443> ServerName <your-riot-domain.com> ProxyPass / http://<riot-internal-ip>:8080/ ProxyPassReverse / http://<riot-internal-ip>:8080/ ProxyRequests On SSLEngine On SSLCertificateFile "</path/to/server.crt>" SSLCertificateKeyFile "</path/to/server.key>" SSLCertificateChainFile "</path/to/ca.crt>" </VirtualHost>
Jitsi
Conferencing tool
Installation
Jitsi installation follows the instructions on the DevOPs Guide (Docker)
from Jitsi Meet Handbook
found at https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker. The ports and configuration paths can be changed as needed (as done in my instance).
Note 1: At the moment, it’s not possible to somehow protect the rooms created by
riot
. The rooms made by riot will not be password protected and asriot
cannot useprosody
‘s user list, it’s not possible to protectjitsi
rooms per default, which means anyone who knows there is a jitsi server on your machine, can connect to it and use is as a conferencing tool.Note 2: Please make sure port
10000/udp
(the same port as inJVB_PORT
in.env
) is also open, otherwise, your calls will drop constantly.
Installation Path
:/home/jitsi
- create the installation path, go it and clone
jitsi/docker-jitsi-meet
into it using:git clone https://github.com/jitsi/docker-jitsi-meet .
. Please note, that the.
in the command is mandatory to force cloning into the current directory, which it’s supposed be/home/jitsi
. - copy
env.example
to.env
. - use
./gen-passwords.sh
to automatically create randomized password strings for the.env
file. - create
config
directories{web/letsencrypt,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri}
underjitsi-meet-cfg
. - go through
.env
parameters and check their validity or configure as needed. A list of availableconfiguration
s can be found in the link posted above, but here an overview of the “important” ones:CONFIG
is the path to your local configuration paths (defined in last step underjitsi-meet-cfg
).TZ
is your timezoneHTTP_PORT
andHTTPS_PORT
are the ports which are to be exposed respectively forhttp
andhttps
connections on docker.PUBLIC_URL
is where your jitsi UI is located. something likehttps://<your-jitsi-domain.com>
…- you can enable
let's encrypt
if you want to forward requests directly to jitsi, or you can use the reverse proxy and define your certificates on that – as with the previous dockers. JVB_PORT
is the Jitsi-VideoBridge port, mentioned above, which needs to be accessible from the outside world, otherwise, the video connections will drop constantly.
- there is no need to change
docker-compose.yml
, as it uses the.env
variables.
Reverse Proxy
<VirtualHost *:443> ServerName <your-jitsi-domain.com> ProxyPass / https://<jitsi-internal-ip>:8043/ ProxyPassReverse / https://<jitsi-internal-ip>:8043/ ProxyRequests On SSLProxyEngine on SSLProxyVerify none SSLProxyCheckPeerCN Off SSLProxyCheckPeerName Off SSLProxyCheckPeerExpire Off SSLEngine On SSLCertificateFile "</path/to/server.crt>" SSLCertificateKeyFile "</path/to/server.key>" SSLCertificateChainFile "</path/to/ca.crt>" </VirtualHost>
Comments are closed, but trackbacks and pingbacks are open.