From 5566a6c099d1278765bbb8b9aa6a7906253c721f Mon Sep 17 00:00:00 2001 From: niten Date: Tue, 10 Oct 2023 17:43:39 -0700 Subject: [PATCH] Add Solr full text search --- dovecot.nix | 68 +++++++++++++++++++++++++++++++++++++++++++++++-- mail-server.nix | 21 +++++++++++++-- 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/dovecot.nix b/dovecot.nix index 027e51d..9441307 100644 --- a/dovecot.nix +++ b/dovecot.nix @@ -157,6 +157,17 @@ in { }; }; + solr = { + host = mkOption { + type = str; + description = "Host providing full-text search with Solr."; + }; + port = mkOption { + type = port; + description = "Port on which Solr is listening."; + }; + }; + max-user-connections = mkOption { type = int; description = "Maximum allowed simultaneous connections by one user."; @@ -201,7 +212,51 @@ in { "d ${cfg.state-directory}/sieves 0750 ${config.services.dovecot2.user} ${config.services.dovecot2.group} - -" ]; - services = { + timers = { + solr-commit = { + wantedBy = [ "timers.target" "dovecot2.service" ]; + timerConfig = { + OnBootSec = "5m"; + OnUnitActiveSec = "5m"; + Unit = "solr-commit.service"; + }; + }; + solr-optimize = { + wantedBy = [ "timers.target" "dovecot2.service" ]; + timerConfig = { + OnBootSec = "5m"; + OnUnitActiveSec = "5m"; + Unit = "solr-optimize.service"; + }; + }; + }; + + services = let + solrJob = params: { + requires = [ "dovecot2.service" ]; + path = with pkgs; [ curl ]; + serviceConfig = { + DynamicUser = true; + ExecStart = + "curl http://${cfg.solr.host}:${cfg.solr.port}/solr/dovecot/update?${params}"; + PrivateDevices = true; + PrivateTmp = true; + PrivateMounts = true; + ProtectControlGroups = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectSystem = true; + ProtectHome = true; + ProtectClock = true; + ProtectKernelLogs = true; + Type = "oneshot"; + }; + }; + in { + solr-commit = solrJob "commit=true"; + + solr-optimize = solrJob "optimize=true"; + prometheus-dovecot-exporter = { requires = [ "dovecot2.service" ]; after = [ "dovecot2.service" ]; @@ -247,6 +302,10 @@ in { Type = "oneshot"; }; }; + + solr-commit = { + + }; }; }; @@ -315,7 +374,7 @@ in { in '' ## Extra Config - mail_plugins = $mail_plugins + mail_plugins = $mail_plugins fts fts_solr ${lib.optionalString cfg.debug '' mail_debug = yes @@ -332,6 +391,11 @@ in { mail_plugins = $mail_plugins sieve } + plugin { + fts = solr + fts_solr = url=http://${cfg.solr.host}:${cfg.solr.port}/solr/dovecot + } + mail_access_groups = ${cfg.mail-group} # When looking up usernames, just use the name, not the full address diff --git a/mail-server.nix b/mail-server.nix index 222b7c3..94f537e 100644 --- a/mail-server.nix +++ b/mail-server.nix @@ -253,6 +253,7 @@ in { authPort = 5447; userdbPort = 5448; dkimPort = 5734; + solrPort = 8983; in { smtp = { @@ -263,6 +264,8 @@ in { "external_network" # For auth lookups "ldap_network" + # For full text search + "solr_network" ]; volumes = [ "${hostSecrets.dovecotLdapConfig.target-file}:/run/dovecot2/conf.d/ldap.conf:ro" @@ -322,8 +325,12 @@ in { }; imap = { service = { - networks = - [ "internal_network" "external_network" "ldap_network" ]; + networks = [ + "internal_network" + "external_network" + "ldap_network" + "solr_network" + ]; ports = [ "143:143" "993:993" ]; volumes = [ "${cfg.state-directory}/dovecot:/state" @@ -361,6 +368,10 @@ in { host = "antispam"; port = antispamPort; }; + solr = { + host = "solr"; + port = solrPort; + }; ldap-conf = "/run/dovecot2/conf.d/ldap.conf"; }; }; @@ -376,6 +387,12 @@ in { ]; env_file = [ hostSecrets.mailLdapProxyEnv.target-file ]; }; + solr.service = { + image = cfg.images.solr; + restart = "always"; + networks = [ "solr_network" ]; + volumes = [ "${cfg.state-directory}/solr:/opt/solr/server/solr" ]; + }; antispam = { service = { networks = [