Run Your Own Matrix Homeserver on NixOS
howto, matrix, nix
Due to current events, alternatives to Discord have been getting a lot of attention recently. As much as I would love for Matrix to succeed here, it isn’t ready for most non-technical users. However, if you are a technical person…
This guide assumes a few things:
- You’ll be running the server on a computer that’s publically accessible over the internet
- You have a domain that points to said machine
- Said machine is running NixOS
Since “Matrix” is a protocol, there are several server implementations - with the most widely used (by far) being Synapse.
It was the first implementation, and it’s used to host the official matrix.org server - however, it has performance issues and eats a bunch of RAM and CPU.
The main alternative, which is what this guide will use, is Continuwuity1.
Continuwuity is packaged in nixpkgs and already has a NixOS module, which makes the setup process just involve enabling the service and some settings:
let your-domain = "example.com";inservices.matrix-continuwuity = { enable = true;
settings.global = { server_name = your-domain;
new_user_displayname_suffix = "";
address = null; unix_socket_path = "/run/continuwuity/continuwuity.sock";
well_known.client = "https://matrix.${your-domain}"; well_known.server = "matrix.${your-domain}:443";
# just in case! lockdown_public_room_directory = true; allow_room_creation = false; require_auth_for_profile_requests = true; # no user enumeration url_preview_domain_explicit_allowlist = [ "github.com" ];
log = "INFO,conduwuit_core::matrix::state_res=off"; # cleaner logs }; };We also need to expose the server to the public internet. Caddy makes this super easy, handles TLS certificates automatically, etc.
let your-domain = "example.com";inservices.caddy = { enable = true; virtualHosts = { "${your-domain}".extraConfig = '' reverse_proxy /.well-known/matrix/* unix//run/continuwuity/continuwuity.sock ''; "matrix.${your-domain}".extraConfig = '' route { @api path /_matrix/* /_continuwuity/* reverse_proxy @api unix//run/continuwuity/continuwuity.sock } ''; };};users.users.caddy.extraGroups = [ "continuwuity" ]; # give caddy access to continuwuity's unix socketnetworking.firewall.allowedTCPPorts = [ 80 443 ];networking.firewall.allowedUDPPorts = [ 443 ];To test that the server is accessible to the wider network, you can use the Matrix Federation Tester.
Now that the server is up, running and working, you need a client to use to connect. I prefer Cinny since it’s a self-contained web application and has a good UI, but there are many others. You can use the official instance the developer runs at app.cinny.im, or deploy your own:
"matrix.${your-domain}".extraConfig = '' route { @api path /_matrix/* /_continuwuity/* reverse_proxy @api unix//run/continuwuity/continuwuity.sock
root * ${ pkgs.cinny.override { conf = { defaultHomeserver = 0; homeserverList = [ your-domain ]; allowCustomHomeservers = false; featuredCommunities = { openAsDefault = false; spaces = [ "#community:matrix.org" "#cinny-space:matrix.org" "#space:continuwuity.org" "#space:nixos.org" ]; rooms = [ ]; servers = [ "matrix.org" "mozilla.org" "nixos.org" ]; }; }; } } try_files {path} / index.html file_server }'';Now it’s time to register your account! Your client will ask for a registration token, which is in the service logs:
sudo journalctl -u continuwuity | grep "registration token"If you run into any issues, the Continuwuity matrix space is super active and helpful. You might need to create an account on different server like matrix.org if your own isn’t fully set up yet :)