{ config, lib, inputs, pkgs, ... }: with lib; let cfg = config.nixfiles.modules.matrix.dendrite; in { options.nixfiles.modules.matrix.dendrite = { enable = mkEnableOption "Dendrite Matrix server"; domain = mkOption { type = types.str; default = config.networking.domain; description = "Domain name sans protocol scheme."; }; }; config = let db = "dendrite"; in mkIf cfg.enable { secrets.dendrite-private-key = { file = "${inputs.self}/secrets/dendrite-private-key"; mode = "0444"; # The user is dynamic so the file must be world-readable. }; secrets.dendrite-environment-file = { file = "${inputs.self}/secrets/dendrite-environment-file"; mode = "0444"; # The user is dynamic so the file must be world-readable. }; nixfiles.modules = { nginx = { enable = true; upstreams.dendrite.servers."127.0.0.1:${toString config.services.dendrite.httpPort}" = {}; virtualHosts.${cfg.domain}.locations = { "/_matrix".proxyPass = "http://dendrite"; "= /.well-known/matrix/server" = { extraConfig = '' add_header Content-Type application/json; ''; return = "200 '${ generators.toJSON {} {"m.server" = "${cfg.domain}:443";} }'"; }; "= /.well-known/matrix/client" = { extraConfig = '' add_header Content-Type application/json; add_header Access-Control-Allow-Origin *; ''; return = "200 '${ generators.toJSON {} { "m.homeserver".base_url = "https://${cfg.domain}"; } }'"; }; }; }; postgresql = { enable = true; extraPostStart = [ '' $PSQL "${db}" -tAc 'GRANT ALL ON SCHEMA "public" TO "${db}"' '' ]; }; }; services = { dendrite = { enable = true; httpPort = 8008; environmentFile = config.secrets.dendrite-environment-file.path; settings = { version = 2; global = { server_name = cfg.domain; private_key = config.secrets.dendrite-private-key.path; database = { connection_string = "postgresql://${db}@/${db}?host=/run/postgresql"; max_open_conns = 64; max_idle_connections = 8; }; cache = { max_size_estimated = "1gb"; max_age = "1h"; }; trusted_third_party_id_servers = [ "matrix.org" "nixos.org" "vector.im" ]; presence = { enable_inbound = false; enable_outbound = false; }; }; client_api = { registration_disabled = true; guests_disabled = true; registration_shared_secret = "$REGISTRATION_SHARED_SECRET"; }; media_api = { max_file_size_bytes = 0; dynamic_thumbnails = true; max_thumbnail_generators = 8; thumbnail_sizes = [ { width = 32; height = 32; method = "crop"; } { width = 96; height = 96; method = "crop"; } { width = 640; height = 480; method = "scale"; } ]; }; logging = [ { type = "std"; level = "warn"; } ]; }; }; postgresql = { ensureDatabases = [db]; ensureUsers = [ { name = db; ensurePermissions."DATABASE \"${db}\"" = "ALL"; } ]; }; }; systemd.services.dendrite.serviceConfig.ExecStart = mkForce (concatStringsSep " " [ "${pkgs.dendrite}/bin/dendrite-monolith-server" "--config /run/dendrite/dendrite.yaml" "--http-bind-address 127.0.0.1:${ toString config.services.dendrite.httpPort }" ]); }; }