Name | Source | Description |
---|---|---|
<CONTAINER_NAME> | User input | The name of the linux container that will be used later to log in with the container. |
<DB_PASSWORD> | User input | The password for logging in with the nextcloud PostgreSQL user. |
<IP_ADDRESS_INET_GW> | Linux VPS Admin Panel | The static and public IPv4 address of the Internet Gateway. |
<IP_ADDRESS_SERVER__VPN> | User input | The IPv4 address of the server on the Edge in the VPN, e.g. 10.5.5.2 . |
<DOMAIN_NAME> | User input | The domain name for the A record created with your domain registrar, e.g. myownliberatededge42.net . |
<TURN_SERVER__HOST> | TURN/STUN server configuration | The domain name or IP address pointing to a running TURN/STUN server, e.g. turn.myownliberatededge42.net . |
<TURN_SERVER__PORT> | TURN/STUN server configuration | The server port for the STUN/TURN server, e.g. 3478 . |
<TURN_SERVER__SHARED_SECRET> | TURN/STUN server configuration | The shared secret for the STUN/TURN server. |
Going through all the steps in this guide shall take around 90 min. with decent Internet connection.
Run the following commands on your server on the Edge.
incus launch images:archlinux/current <CONTAINER_NAME>
incus exec <CONTAINER_NAME> bash
vi /etc/pacman.conf
Un-comment ParallelDownloads = 5
.
vi /etc/locale.gen
Un-comment the needed locales.
locale-gen
vi /etc/locale.conf
Set LANG to a generated system locale.
reboot
incus exec <CONTAINER_NAME> bash
pacman -S archlinux-keyring && pacman -Syyuu fish
chsh -s /usr/bin/fish
From here on the root user will use fish
as default shell.
timedatectl set-ntp no
pacman -Syyuu ntp
systemctl enable ntpd
systemctl start ntpd
Find the time zone you'd like to set up for this container.
timedatectl list-timezones
And set it up. For example
timedatectl set-timezone Europe/Berlin
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
passwd
Set a password for the root user and make a (mental) note of it. It will be denoted with a variable <ROOT_PWD__CONTAINER>.
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec liberatededge-wiki fish
pacman -S archlinux-keyring && pacman -Syyuu postgresql
su - postgres -c \
'initdb --locale=C.UTF-8 --encoding=UTF8 -D /var/lib/postgres/data --data-checksums'
Make sure that following settings will be reflected in /etc/postgresql/15/main/postgresql.conf
.
Note that the path is dependent on the version of the database engine. In this particular case the version is
15
.
max_connections = 100
shared_buffers = 2GB
effective_cache_size = 6GB
maintenance_work_mem = 512MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200
work_mem = 5242kB
min_wal_size = 1GB
max_wal_size = 4GB
The configuration is generated by a tool. It uses an assumption for the "machine" hosting the database. This server machine is supposed to have 2 CPU cores, RAM 8Gb and SSD storage. You can generate more personalised configurations.
systemctl enable postgresql
systemctl start postgresql
Verify that the stage has been completed successfully by running the following command in the container. Its output should indicate that the service is running.
systemctl status postgresql
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER-NAME> fish
Take a not of the password for the database user. It will be denoted with a variable <DB_PASSWORD>.
sudo -u postgres \
createuser dendrite --interactive --pwprompt
Take a note of the password <DB_PASSWORD>.
sudo -u postgres \
createdb dendrite -O dendrite --encoding='utf-8'
useradd dendrite
cd /opt
git clone https://github.com/matrix-org/dendrite
chown -R dendrite:dendrite dendrite
cd dendrite
sudo -u dendrite ./build.sh
mkdir -p /var/lib/dendrite
chown -R dendrite:dendrite /var/lib/dendrite
mkdir -p /var/log/dendrite
chown -R dendrite:dendrite /var/log/dendrite
mkdir -p /etc/dendrite
You can copy the sample dendrite configuration and tweak it.
cp dendrite-sample.yaml /etc/dendrite/config.yaml
or you can manually create /etc/dendrite/config.yaml
and add the following content.
Don't forget to substitute the following variables DOMAIN_NAME and DB_PASSWORD with their respective values that you should have captured by now.
version: 2
global:
server_name: matrix.<DOMAIN_NAME>
key_id: ed25519:auto
private_key: matrix_key.pem
old_private_keys: []
key_validity_period: 168h0m0s
database:
connection_string: postgresql://dendrite:<DB_PASSWORD>@127.0.0.1/dendrite?sslmode=disable
max_open_conns: 90
max_idle_conns: 5
conn_max_lifetime: -1
well_known_server_name: ""
well_known_client_name: ""
disable_federation: false
presence:
enable_inbound: false
enable_outbound: false
trusted_third_party_id_servers:
- matrix.org
- vector.im
jetstream:
storage_path: /var/lib/dendrite
addresses: []
topic_prefix: Dendrite
in_memory: false
disable_tls_validation: true
metrics:
enabled: false
basic_auth:
username: metrics
password: metrics
sentry:
enabled: false
dsn: ""
environment: ""
dns_cache:
enabled: true
cache_size: 4096
cache_lifetime: 600s
server_notices:
enabled: true
local_part: _server
display_name: Server Alert
avatar_url: ""
room_name: Server Alert
report_stats:
enabled: false
endpoint: https://matrix.org/report-usage-stats/push
cache:
max_size_estimated: 2gb
max_age: 1h0m0s
app_service_api:
disable_tls_validation: false
config_files: []
client_api:
registration_disabled: true
registration_shared_secret: "w*6@p*^8Mc%RGBnqS$zmoeTHiCbPZ6qVtbx*9AcoT4Rc@k*byfRzD5eRACq5hg3rfFyiq2NeXHYb!DM$!9Qe2h4pdvUi3Dtp33es%Du8^Hm7wW6Tm6ML^DSZqmYinkan"
guests_disabled: false
enable_registration_captcha: false
recaptcha_api_js_url: ""
recaptcha_sitekey_class: ""
recaptcha_form_field: ""
recaptcha_public_key: ""
recaptcha_private_key: ""
recaptcha_bypass_secret: ""
recaptcha_siteverify_api: ""
turn:
turn_user_lifetime: ""
turn_uris: []
turn_shared_secret: ""
turn_username: ""
turn_password: ""
rate_limiting:
enabled: true
threshold: 5
cooloff_ms: 500
exempt_user_ids: []
federation_api:
database:
connection_string: file:/var/lib/dendrite/dendrite_federationapi.db
max_open_conns: 0
max_idle_conns: 0
conn_max_lifetime: 0
send_max_retries: 16
p2p_retries_until_assumed_offline: 1
disable_tls_validation: false
disable_http_keepalives: false
key_perspectives:
- server_name: matrix.org
keys:
- key_id: ed25519:auto
public_key: Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw
- key_id: ed25519:a_RXGa
public_key: l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ
prefer_direct_fetch: false
key_server:
database:
connection_string: file:/var/lib/dendrite/dendrite_keyserver.db
max_open_conns: 0
max_idle_conns: 0
conn_max_lifetime: 0
media_api:
database:
connection_string: file:/var/lib/dendrite/dendrite_mediaapi.db
max_open_conns: 0
max_idle_conns: 0
conn_max_lifetime: 0
base_path: /var/lib/dendrite/media
max_file_size_bytes: 10485760
dynamic_thumbnails: false
max_thumbnail_generators: 10
thumbnail_sizes:
- width: 32
height: 32
method: crop
- width: 96
height: 96
method: crop
- width: 640
height: 480
method: scale
room_server:
database:
connection_string: file:/var/lib/dendrite/dendrite_roomserver.db
max_open_conns: 0
max_idle_conns: 0
conn_max_lifetime: 0
sync_api:
database:
connection_string: file:/var/lib/dendrite/dendrite_syncapi.db
max_open_conns: 0
max_idle_conns: 0
conn_max_lifetime: 0
real_ip_header: ""
search:
enabled: false
index_path: /var/lib/dendrite/searchindex
in_memory: false
language: en
user_api:
bcrypt_cost: 10
openid_token_lifetime_ms: 3600000
push_gateway_disable_tls_validation: false
account_database:
connection_string: file:/var/lib/dendrite/dendrite_userapi.db
max_open_conns: 0
max_idle_conns: 0
conn_max_lifetime: 0
auto_join_rooms: []
relay_api: {}
mscs:
mscs: []
database:
connection_string: file:/var/lib/dendrite/dendrite_mscs.db
max_open_conns: 0
max_idle_conns: 0
conn_max_lifetime: 0
tracing:
enabled: false
jaeger:
serviceName: ""
disabled: false
rpc_metrics: false
traceid_128bit: false
tags: []
sampler: null
reporter: null
headers: null
baggage_restrictions: null
throttler: null
logging:
- type: file
level: info
params:
path: /var/lib/dendrite/log
sudo -u dendrite ./bin/generate-keys \
--private-key /var/lib/dendrite/matrix_key.pem
sudo -u dendrite ./bin/generate-keys \
--tls-cert /var/lib/dendrite/server.crt \
--tls-key /var/lib/dendrite/server.key
vi /usr/lib/systemd/system/dendrite.service
Add the following content to the service file.
[Unit]
Description=Dendrite Matrix Homeserver
After=network-online.target
After=postgresql.service
Wants=postgresql.service
[Service]
User=dendrite
ExecStart=/opt/dendrite/bin/dendrite --tls-cert=/var/lib/dendrite/server.crt --tls-key=/var/lib/dendrite/server.key --config=/etc/dendrite/config.yaml
WorkingDirectory=/var/lib/dendrite/
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable dendrite
systemctl start dendrite
Create an administrative dendrite
user
sudo -u dendrite /opt/dendrite/bin/create-account \
--config=/etc/dendrite/config.yaml \
--admin \
--username admin
Don't forget to substitute the variable <REGULAR_USER> with an username for a non-administrative user.
sudo -u dendrite /opt/dendrite/bin/create-account \
--config=/etc/dendrite/config.yaml \
--username <REGULAR_USER>
On the server on Edge run the following command.
incus config device add <CONTAINER-NAME> port8448 \
proxy listen=tcp:0.0.0.0:8448 \
connect=tcp:127.0.0.1:8448
ssh mycelium@<IP_ADDRESS__INET_GW>
sudo su -
Append the following reverse proxy configuration to /etc/caddy/Caddyfile
.
# reverse proxy to Dendrite, both :443 and :8448
matrix.<DOMAIN_NAME> matrix.<DOMAIN_NAME>:8448 {
tls tls@<DOMAIN_NAME>
header /.well-known/matrix/*Content-Type application/json
header /.well-known/matrix/* Access-Control-Allow-Origin *
respond /.well-known/matrix/server `{"m.server": "matrix.<DOMAIN_NAME>:443"}`
respond /.well-known/matrix/client `{"m.homeserver": {"base_url": "https://matrix.<DOMAIN_NAME>"}}`
handle /_matrix/* {
reverse_proxy <IP_ADDRESS_SERVER__VPN>:8448 {
transport http {
tls
tls_insecure_skip_verify
}
}
}
}
systemctl reload caddy
systemctl status caddy
The systemd service should be up & running.
Make sure that you have created an "A" domain record for the subdomain matrix.<DOMAIN_NAME> with your domain registrar and you have waited for this record to become active.
If the "A" record is not updated yet, Caddy will not be able to serve HTTPS requests because of Let's Encrypt (An SSL certificate authority) failing to verify the validity (ownership over) of the domain.
You should be able to use a Matrix client such as Element or Fluffy Chat to connect to your homeserver
https://matrix.<DOMAIN_NAME>
, exchange text messages and share photos and videos. Voice and video calls will not be possible unless you configuredendrite
to use a TURN/STUN server.
In order to enable voice and video calls one needs to configure dendrite
to use a STUN/TURN server. The most pragmatic way is to host and run such a server on an Internet Gateway of yours.
incus exec <CONTAINER_NAME> bash
/etc/dendrite/config.yaml
will include the following configuration. turn:
turn_user_lifetime: "1h"
turn_uris:
- "turn:<TURN_SERVER__HOST>:<TURN_SERVER__PORT>?transport=udp"
- "turn:<TURN_SERVER__HOST>:<TURN_SERVER__PORT>?transport=tcp"
turn_shared_secret: "<TURN_SERVER__SHARED_SECRET>"
turn_allow_guests: true
dendrite
systemd servicesystemctl restart dendrite
Use the Matrix test tool to make sure that the whole set up is correct. Once you make it through green/yellow statuses for all checks, voice and video calls will be enabled for your Dendrite instance. You will be able to have voice and video calls with other users of your homeserver.