summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-xflake.nix44
-rw-r--r--host/Module-dev/configuration.nix55
-rw-r--r--host/Module-dev/set/matrix/postgres.nix22
-rw-r--r--host/Module-dev/set/matrix/root.nix202
-rwxr-xr-xmodules/base.nix2
-rw-r--r--modules/software-templates/synapse-workers/generic.nix62
-rw-r--r--modules/software-templates/synapse-workers/module.nix91
7 files changed, 361 insertions, 117 deletions
diff --git a/flake.nix b/flake.nix

index 7cd106d..97e06f1 100755 --- a/flake.nix +++ b/flake.nix
@@ -84,49 +84,13 @@ with inputs; { nixosConfigurations = { - micro = nixpkgs.lib.nixosSystem { + Module-dev = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ - ./hardware-configuration.nix - #MatrixContentFilter.modules.default - - ( - { ... }: - { - nixpkgs.crossSystem = { - system = "riscv64-linux"; - }; - #boot.isContainer = true; - #system.stateVersion = "0"; - #services.MatrixContentFilter = { - # enable = true; - # accessTokenPath = "/"; - # appSettings = { - # "Logging" = { - # "LogLevel" = { - # "Default" = "Debug"; - # "System" = "Information"; - # "Microsoft" = "Information"; - # }; - # }; - # "LibMatrixBot" = { - # "Homeserver" = "rory.gay"; - # "Prefixes" = [ - # "!mcf " - # ]; - # "MentionPrefix" = false; - # }; - # "MatrixContentFilter" = { - # Admins = [ "@emma:rory.gay" ]; - # }; - # }; - #}; - } - ) + ./host/Module-dev/configuration.nix + home-manager.nixosModules.home-manager + lix-module.nixosModules.default ]; - #specialArgs = { - # inherit home-manager; - #}; }; Rory-nginx = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; diff --git a/host/Module-dev/configuration.nix b/host/Module-dev/configuration.nix new file mode 100644
index 0000000..f3f66fe --- /dev/null +++ b/host/Module-dev/configuration.nix
@@ -0,0 +1,55 @@ +{ + pkgs, + lib, + grapevine, + ... +}: + +{ + imports = [ + ../../modules/base-server.nix + ./set/matrix/root.nix + ]; + + networking = { + hostName = "Module-dev"; + useDHCP = lib.mkForce true; + defaultGateway.interface = "eth0"; + nat = { + enable = true; + internalInterfaces = [ + "ve-+" + "vb-+" + ]; + externalInterface = "ens18"; + enableIPv6 = false; + }; + enableIPv6 = lib.mkForce false; + nameservers = lib.mkForce [ "192.168.1.1" ]; + }; + + monitoring = { + monitorAll = true; + localPrometheus = true; + exposePrometheus = true; + localGrafana = true; + exposeGrafana = true; + nginxHost = "monitoring.rory.gay"; + nginxSsl = true; + }; + + nixpkgs.config.permittedInsecurePackages = [ + "olm-3.2.16" + "dotnet-runtime-wrapped-7.0.20" + "dotnet-runtime-7.0.20" + "dotnet-sdk-7.0.20" + ]; + services.irqbalance.enable = true; + + environment.memoryAllocator.provider = "jemalloc"; + + system.stateVersion = lib.trivial.release; # DO NOT copy to real configs! + + environment.systemPackages = with pkgs; [ waypipe ]; + nix.nrBuildUsers = 128; +} diff --git a/host/Module-dev/set/matrix/postgres.nix b/host/Module-dev/set/matrix/postgres.nix new file mode 100644
index 0000000..0a6a8d7 --- /dev/null +++ b/host/Module-dev/set/matrix/postgres.nix
@@ -0,0 +1,22 @@ +{ pkgs, ... }: + +{ + services.postgresql = { + enable = true; + package = pkgs.postgresql_17_jit; + enableTCPIP = true; + authentication = pkgs.lib.mkOverride 10 '' + # TYPE, DATABASE, USER, ADDRESS, METHOD + local all all trust + host all all 127.0.0.1/32 trust + host all all ::1/128 trust + host discordbots discordbots 192.168.1.2/32 trust + host matrix-synapse-rory-gay matrix-synapse-rory-gay 192.168.1.5/32 trust + host all all 0.0.0.0/0 md5 + ''; + settings = { + max_connections = 2500; + superuser_reserved_connections = 3; + }; + }; +} diff --git a/host/Module-dev/set/matrix/root.nix b/host/Module-dev/set/matrix/root.nix new file mode 100644
index 0000000..22fb2d9 --- /dev/null +++ b/host/Module-dev/set/matrix/root.nix
@@ -0,0 +1,202 @@ +{ pkgs, config, ... }: + +let + mkWorker = + name: tasks: + import ../../../../modules/software-templates/synapse-workers/generic.nix { + workerName = name; + tasks = tasks; + }; +in +{ + # Worker plumbing examples: https://github.com/element-hq/synapse/blob/master/docker/configure_workers_and_start.py + # Documentation: https://github.com/element-hq/synapse/blob/develop/docs/workers.md + imports = [ + ../../../../modules/software-templates/synapse-workers/module.nix + ./postgres.nix + + (mkWorker "sync" [ "sync" ]) + ]; + + services.matrix-synapse = { + enable = true; + withJemalloc = true; + + nginxVirtualHostName = "matrix.rory.gay"; + enableWorkers = true; + + federationSenders = 16; # 16 + pushers = 1; + mediaRepoWorkers = 2; # 4 + clientReaders = 2; # 4 + syncWorkers = 2; # 4 + authWorkers = 0; + + eventCreators = 16; + + federationReaders = 8; # 8 + federationInboundWorkers = 16; # 8 + + enableAppserviceWorker = true; + enableBackgroundWorker = true; + enableUserDirWorker = true; + + accountDataStreamWriters = 1; + eventStreamWriters = 2; # 8 + presenceStreamWriters = 1; + pushRuleStreamWriters = 1; + receiptStreamWriters = 1; + toDeviceStreamWriters = 1; + typingStreamWriters = 1; + + # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html + settings = { + server_name = "rory.gay"; + + dummy_devents_treshold = 2; + cleanup_extremities_with_dummy_events = true; + + enable_registration = true; + registration_requires_token = true; + + require_membership_for_aliases = false; + redaction_retention_period = null; + user_ips_max_age = null; + allow_device_name_lookup_over_federation = true; + + federation = { + client_timeout = "30s"; # default=60s + max_short_retries = 12; + max_short_retry_delay = "5s"; + max_long_retries = 5; + max_long_retry_delay = "30s"; + + # rapid retry, small increments + destination_min_retry_interval = "5m"; # default=10m + destination_max_retry_interval = "12h"; # default=7d + destination_retry_multiplier = 1.2; # default=2 + }; + + registration_shared_secret_path = pkgs.writeText "registration_shared_secret.txt" '' + sometext + ''; + + listeners = [ + { + port = 8008; + bind_addresses = [ "127.0.0.1" ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = [ + { + names = [ + "client" + "federation" + ]; + compress = false; + } + ]; + } + { + type = "http"; + path = "/run/matrix-synapse/main.sock"; + resources = [ + { + names = [ "replication" ]; + compress = false; + } + ]; + } + ]; + presence = { + enablee = true; + update_interval = 60; + }; + database = { + name = "psycopg2"; + args = { + user = "matrix-synapse-rory-gay"; + password = "somepassword"; + database = "matrix-synapse-rory-gay"; + host = "/run/postgresql"; + application_name = "matrix-synapse (rory.gay) - main"; + cp_min = 2; + cp_max = 5; + + # cp_reconnect - default=True - https://github.com/element-hq/synapse/blob/develop/synapse/storage/database.py#L129 + # cp_noisy - default=False - https://docs.twisted.org/en/stable/api/twisted.enterprise.adbapi.ConnectionPool.html#__init__ - info logs during operation + # check_same_thread - default=False - https://github.com/element-hq/synapse/blob/develop/synapse/config/database.py#L65 - can this even be set? + }; + + # synchronous_commit - default=True - https://github.com/element-hq/synapse/blob/develop/synapse/storage/engines/postgres.py#L56 + # statement_timeout - default=60 * 60 * 1000 ms - https://github.com/element-hq/synapse/blob/develop/synapse/storage/engines/postgres.py#L63 + # allow_unsafe_locale - default=False - https://github.com/element-hq/synapse/blob/develop/synapse/storage/engines/postgres.py#L99 + # allow_outdated_version - default=False - https://github.com/element-hq/synapse/blob/develop/synapse/storage/engines/postgres.py#L92 - needs source link + # txn_limit - default=0 - https://github.com/element-hq/synapse/blob/develop/synapse/storage/database.py#L564 + + statement_timeout = 24 * 60 * 60 * 1000; # 24 hours, good for bg jobs + txn_limit = 500; # maybe dropping old data from pg caches helps? + }; + + ui_auth = { + session_timeout = "1m"; + }; + + login_via_existing_session = { + enabled = true; + require_ui_auth = true; + token_timeout = "1y"; + }; + + report_stats = false; + + user_directory = { + enabled = true; + search_all_users = true; + prefer_local_users = true; + }; + + # https://github.com/element-hq/synapse/blob/master/synapse/config/experimental.py + experimental_features = { + "msc2815_enabled" = true; # Redacted event content + "msc3026_enabled" = true; # Busy presence + "msc3266_enabled" = true; # Room summary API + "msc3916_authenticated_media_enabled" = true; # Authenticated media + "msc3823_account_suspension" = true; # Account suspension + "msc4151_enabled" = true; # Report room API (CS-API) + }; + + redis = { + enabled = true; + path = "/run/redis-matrix-synapse/redis.sock"; + }; + + instance_map = { + main = { + # replication listener + path = "/run/matrix-synapse/main.sock"; + }; + }; + }; + # // import ./ratelimits.nix + # // import ./caches.nix; + }; + + services.redis = { + package = pkgs.keydb; + servers.matrix-synapse = { + enable = true; + user = "matrix-synapse"; + }; + }; + + services.postgresql = { + initialScript = pkgs.writeText "synapse-init.sql" '' + CREATE USER "${config.services.matrix-synapse.settings.database.args.user}" WITH PASSWORD '${config.services.matrix-synapse.settings.database.args.password}'; + CREATE DATABASE "${config.services.matrix-synapse.settings.database.args.database}" OWNER '${config.services.matrix-synapse.settings.database.args.user}' LOCALE 'C' ENCODING 'UTF8' TEMPLATE "template0"; + ''; + }; + + systemd.tmpfiles.rules = [ "D /run/redis-matrix-synapse 0755 matrix-synapse matrix-synapse" ]; +} diff --git a/modules/base.nix b/modules/base.nix
index f2f8f57..e366f59 100755 --- a/modules/base.nix +++ b/modules/base.nix
@@ -174,7 +174,7 @@ services.getty.autologinUser = "root"; virtualisation = { memorySize = 4096; - cores = 6; + cores = 2; msize = 1*1024*1024; bios = pkgs.qboot; }; diff --git a/modules/software-templates/synapse-workers/generic.nix b/modules/software-templates/synapse-workers/generic.nix
index 5e540b3..d524baf 100644 --- a/modules/software-templates/synapse-workers/generic.nix +++ b/modules/software-templates/synapse-workers/generic.nix
@@ -1,18 +1,25 @@ +{ + workerName, + tasks, + dbOverrides ? { }, + count ? 1, +}: { config, lib, ... }: +#let +# dbGroup = "medium"; +# workerName = "account_data_stream_writer"; +# tasks = [ "stream_account_data" ]; +## workerRoutes = workerLib.workerRoutes.accountData; +# count = 1; +#in let + workerLib = import ./lib.nix; cfg = config.services.matrix-synapse; - workerLib = import ../lib.nix; - dbGroup = "medium"; -# streamWriterType = "account_data"; - workers = lib.range 0 (cfg.accountDataStreamWriters - 1); - workerName = "account_data_stream_writer"; - tasks = [ "stream_account_data" ]; - workerRoutes = workerLib.workerRoutes.accountData; -in -let enabledResources = lib.attrNames workerRoutes; - streamTypes = [] + workers = lib.range 0 count; + streamTypes = + [ ] ++ lib.optional (lib.elem "stream_account_data" tasks) "account_data" ++ lib.optional (lib.elem "stream_presence" tasks) "presence" ++ lib.optional (lib.elem "stream_push_rules" tasks) "push_rules" @@ -20,10 +27,14 @@ let ++ lib.optional (lib.elem "stream_typing" tasks) "typing" ++ lib.optional (lib.elem "stream_receipts" tasks) "receipts" ++ lib.optional (lib.elem "stream_events" tasks) "events"; + + # recursive update list of attrs +# recursiveMerge = list: lib.foldl (a: b: lib.recursiveUpdate a b) (lib.head list) (lib.tail list); +# workerRoutes = recursiveMerge (lib.map (type: workerLib.workerRoutes.${type}) streamTypes); in { config = lib.mkIf (cfg.accountDataStreamWriters > 0) { - monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers; + monitoring.synapse.workerNames = if (count == 1) then [ workerName ] else lib.map (index: "${workerName}-${toString index}") workers; services.matrix-synapse = { settings = { instance_map = lib.listToAttrs ( @@ -35,9 +46,6 @@ in }) workers ); - #stream_writers.${streamWriterType} = lib.map (index: "${workerName}-${toString index}") workers; -# stream_writers = lib.listToA - # map `streams` to `workers` stream_writers = lib.listToAttrs ( lib.map (stream: { name = stream; @@ -75,12 +83,26 @@ in } ]; }) enabledResources; - database = ( - import ../../db.nix { - inherit dbGroup; - workerName = "${workerName}-${toString index}"; - } - ); + database = lib.recursiveUpdate (lib.recursiveUpdate config.services.matrix-synapse.settings.database { + application_name = "matrix-synapse (${config.services.matrix-synapse.settings.server_name}) - ${if workerName == null then throw "synapse/db.nix: workerName unspecified" else workerName}"; + }) dbOverrides; + + #region Media + max_upload_size = lib.mkIf (lib.elem "media_repo" tasks) "512M"; + max_avatar_size = lib.mkIf (lib.elem "media_repo" tasks) "512M"; + max_image_pixels = lib.mkIf (lib.elem "media_repo" tasks) "250M"; + + max_pending_media_uploads = lib.mkIf (lib.elem "media_repo" tasks) 512; + dynamic_thumbnails = lib.mkIf (lib.elem "media_repo" tasks) true; + + prevent_media_downloads_from = lib.mkIf (lib.elem "media_repo" tasks) [ + # none, give me all the media + ]; + enable_authenticated_media = lib.mkIf (lib.elem "media_repo" tasks) false; + + url_preview_enabled = lib.mkIf (lib.elem "media_repo" tasks) true; + max_spider_size = lib.mkIf (lib.elem "media_repo" tasks) "50M"; + #endregion }; }) workers ); diff --git a/modules/software-templates/synapse-workers/module.nix b/modules/software-templates/synapse-workers/module.nix
index 5a40045..b1d0ced 100644 --- a/modules/software-templates/synapse-workers/module.nix +++ b/modules/software-templates/synapse-workers/module.nix
@@ -11,29 +11,6 @@ let in { imports = [ - ./single/appservice.nix - ./single/background.nix - ./single/user-dir.nix - - ./auth.nix - ./client-reader.nix - ./event-creator.nix - ./federation-inbound.nix - ./federation-reader.nix - ./federation-sender.nix - ./media-repo.nix - ./pusher.nix - ./sync.nix - - ./stream-writers/account_data-stream-writer.nix - ./stream-writers/event-stream-writer.nix - ./stream-writers/presence-stream-writer.nix - ./stream-writers/push_rule-stream-writer.nix - ./stream-writers/receipt-stream-writer.nix - ./stream-writers/to_device-stream-writer.nix - ./stream-writers/typing-stream-writer.nix - - # ./stream-writers/shared-stream-writer.nix ]; options.services.matrix-synapse = { enableWorkers = lib.mkEnableOption "Enable dedicated workers"; @@ -77,39 +54,41 @@ in }; config = { - assertions = [ - { - assertion = cfg.enableWorkers -> cfg.nginxVirtualHostName != null; - message = "nginxVirtualHostName must be set when enableWorkers is true"; - } - - # Stream types and count limitations: https://github.com/element-hq/synapse/blob/develop/synapse/config/workers.py#L344 - { - assertion = lib.length cfg.settings.stream_writers.typing <= 1; - message = "Only one typing stream writer is supported"; - } - { - assertion = lib.length cfg.settings.stream_writers.to_device <= 1; - message = "Only one to_device stream writer is supported"; - } - { - assertion = lib.length cfg.settings.stream_writers.account_data <= 1; - message = "Only one account data stream writer is supported"; - } - # This may be outdated in the documentation...? - #{ - # assertion = cfg.receiptStreamWriters <= 1; - # message = "Only one receipt stream writer is supported"; - #} - { - assertion = lib.length cfg.settings.stream_writers.presence <= 1; - message = "Only one presence stream writer is supported"; - } - { - assertion = lib.length cfg.settings.stream_writers.push_rules <= 1; - message = "Only one push rule stream writer is supported"; - } - ]; + assertions = + [ + { + assertion = cfg.enableWorkers -> cfg.nginxVirtualHostName != null; + message = "nginxVirtualHostName must be set when enableWorkers is true"; + } + ] + ++ lib.optionals (cfg.settings ? stream_writers) [ + # Stream types and count limitations: https://github.com/element-hq/synapse/blob/develop/synapse/config/workers.py#L344 + { + assertion = cfg.settings.stream_writers ? typing -> lib.length cfg.settings.stream_writers.typing <= 1; + message = "Only one typing stream writer is supported"; + } + { + assertion = cfg.settings.stream_writers ? to_device -> lib.length cfg.settings.stream_writers.to_device <= 1; + message = "Only one to_device stream writer is supported"; + } + { + assertion = cfg.settings.stream_writers ? account_data -> lib.length cfg.settings.stream_writers.account_data <= 1; + message = "Only one account data stream writer is supported"; + } + # This may be outdated in the documentation...? + #{ + # assertion = cfg.receiptStreamWriters <= 1; + # message = "Only one receipt stream writer is supported"; + #} + { + assertion = cfg.settings.stream_writers ? presence -> lib.length cfg.settings.stream_writers.presence <= 1; + message = "Only one presence stream writer is supported"; + } + { + assertion = cfg.settings.stream_writers ? push_rules -> lib.length cfg.settings.stream_writers.push_rules <= 1; + message = "Only one push rule stream writer is supported"; + } + ]; # Matrix utility maps services.nginx.appendHttpConfig = ''