Installing
The server is a Matrix homeserver: it keeps accounts, rooms and messages, and clients such as the Uniform Chat apps or Element connect to it. One program runs it either with a dashboard in the terminal, or without one as a background service.
Note
The server is in early development. Accounts, rooms, messages, room state and sync work, as do profiles, presence, typing, read receipts, unread counts, push rules and push notifications through push gateways, room tags, previews of linked pages (when turned on), room aliases, the public room directory, user search, files and images with thumbnails, and end-to-end encryption with cross-signing, emoji verification and key backup. Federation with other servers is being built and is off by default: with Federation:Enabled, users can look up profiles on other servers, join their rooms and talk there, and browse their public room directories, and other servers' users can join rooms here.
Requirements
- Linux or Windows; for the dashboard, a terminal that supports UTF-8 and colors
Apt install
On Debian and Ubuntu, x64 and arm64, install from the apt repository of Uniform Chat, which is kept in its releases on GitHub. Add the repository once, with the key its packages are signed with:
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://github.com/tagcode/Uniform.Chat/releases/latest/download/uniform-chat-archive-keyring.gpg | sudo tee /etc/apt/keyrings/uniform-chat.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/uniform-chat.gpg] https://github.com/tagcode/Uniform.Chat/releases/ latest/download/" | sudo tee /etc/apt/sources.list.d/uniform-chat.list
sudo apt update
Then install the server:
sudo apt install uniform-chat-server
The package sets the server up as a system service, uniform-chat-server, run by the system user uniform-chat, which it creates:
| What | Where |
|---|---|
| Program | /opt/uniform-chat/server, also as the command uniform-chat-server |
| Settings | /etc/uniform-chat-server/settings.json |
| Database, signing key, files and logs | /var/lib/uniform-chat-server |
The service is off until you write the settings, see the example setup below, and enable it:
sudo systemctl enable --now uniform-chat-server
Run without the dashboard tells more about the service. sudo apt upgrade updates the server with the rest of the system and restarts a running service; back up /var/lib/uniform-chat-server first, see Updating.
From the release archives
Download uniform-chat-server-<version>-linux-x64.tar.gz (or linux-arm64, or win-x64.zip and win-arm64.zip for Windows) from the releases and unpack it anywhere. It needs nothing else installed. The program is uniform-chat-server, or uniform-chat-server.exe on Windows. The docs folder in it has this guide; open docs/index.html in a browser. To run it as a service, see Run without the dashboard.
From source
Install the .NET 10 SDK; then use dotnet run --project src/Uniform.Chat.Server -- from the repository root in place of the program in the examples below.
Example setup
A typical server on the internet runs behind a reverse proxy, such as nginx, which holds the HTTPS certificate; the server itself listens on plain HTTP on the same machine only. The example below is for example.org, with federation, sign-up by registration token, and voice calls through a TURN server; change the names, and leave out what you do not use.
Write the settings to ~/.config/uniform-chat-server/settings.json of the user that runs the server, or, as a system service, to /etc/uniform-chat-server/settings.json. Make the file readable only by that user, as it holds secrets.
{
"Host": { "Ui": "None" },
"Urls": "http://127.0.0.1:8008",
"Server": {
"ServerName": "example.org",
"PublicBaseUrl": "https://example.org",
"TrustedProxies": "127.0.0.1",
"Registration": "Token",
"RegistrationTokens": "a-long-random-token"
},
"Federation": {
"Enabled": true,
"WellKnownServer": "example.org:443"
},
"Calls": {
"TurnUris": "turn:turn.example.org:3478?transport=udp,turn:turn.example.org:3478?transport=tcp",
"TurnSharedSecret": "the TURN server's static-auth-secret"
}
}
| Part | Why |
|---|---|
Urls |
Plain HTTP on this machine only; nginx in front serves HTTPS. Another port than 8008 if something, such as Synapse, uses it. |
ServerName, PublicBaseUrl |
The name in user IDs, and the address clients reach; the server announces it in /.well-known/matrix/client. Choose the name before creating accounts. |
TrustedProxies |
nginx's address, so that rate limits and logs see each client's own address. |
Registration, RegistrationTokens |
Anyone with a token can sign up; share the token with the people you invite. Open lets anyone sign up, Disabled no one. |
Federation |
Talk with other Matrix servers. WellKnownServer is announced in /.well-known/matrix/server, so other servers reach this one on port 443 through nginx, and port 8448 need not be open. |
Calls |
TURN servers for 1:1 calls, e.g. coturn with use-auth-secret and the same static-auth-secret; the server hands clients time-limited credentials. Leave the section out without a TURN server, or use the built-in one, see Calls through firewalls. |
Settings lists every option.
The nginx site, e.g. /etc/nginx/sites-available/example.org, enabled with a link in sites-enabled, passes Matrix's paths to the server, with a certificate from certbot:
# HTTP: certbot's challenges, everything else to HTTPS
server {
listen 80;
listen [::]:80;
server_name example.org;
location /.well-known/acme-challenge/ { root /var/www/html; }
location / { return 301 https://$host$request_uri; }
}
# HTTPS: clients and other servers
server {
# HTTP/2 as a listen flag, which nginx before 1.25.1 needs, e.g. Ubuntu's; newer ones prefer "http2 on;"
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.org;
ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;
# Files people upload; at least Media:MaxUploadSize
client_max_body_size 100M;
location ~ ^/(_matrix|\.well-known/matrix)/ {
proxy_pass http://127.0.0.1:8008;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
# Sync waits for new messages, and joining rooms on other servers can be slow
proxy_read_timeout 600s;
proxy_send_timeout 600s;
proxy_buffering off;
}
}
To get the certificate, enable first only the HTTP part, and run:
sudo certbot certonly --webroot -w /var/www/html -d example.org
sudo nginx -t && sudo systemctl reload nginx
For video calls in Element X through the homeserver's LiveKit service, the location line must also pass /livekit/jwt; see Video calls in Element X.
Then enable the HTTPS part, reload nginx again, and start the server. Check from another computer that https://example.org/.well-known/matrix/server answers {"m.server":"example.org:443"}; the federation tester then shows whether other servers can reach yours. Leave out the [::] lines when the name has no IPv6 address.