{ config, lib, pkgs, self, ... }: let # Source: https://github.com/NixOS/nixpkgs/blob/nixos-22.11/nixos/modules/services/mail/mailman.nix#L9C10-L10 # webEnv is required by the mailman-uwsgi systemd service inherit (pkgs.mailmanPackages.buildEnvs {}) webEnv; in { networking.firewall.allowedTCPPorts = [25]; services.postfix = { enable = true; relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"]; # get TLS certs for list.pub.solar from caddy # TODO: when caddy renews certs, postfix doesn't know about it # implement custom built caddy with events exec handler or systemd-reload # hook so postfix reloads, too sslCert = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/list.pub.solar/list.pub.solar.crt"; sslKey = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/list.pub.solar/list.pub.solar.key"; config = { transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"]; local_recipient_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"]; }; rootAlias = "admins@pub.solar"; postmasterAlias = "admins@pub.solar"; hostname = "list.pub.solar"; }; systemd.paths.watcher-caddy-ssl-file = { description = "Watches for changes in caddy's TLS cert file (after renewals) to reload postfix"; documentation = ["systemd.path(5)"]; partOf = ["postfix-reload.service"]; pathConfig = { PathChanged = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/list.pub.solar/list.pub.solar.crt"; Unit = "postfix-reload.service"; }; wantedBy = ["multi-user.target"]; }; systemd.services."postfix-reload" = { description = "Reloads postfix config, e.g. after TLS certs change, notified by watcher-caddy-ssl-file.path"; documentation = ["systemd.path(5)"]; requires = ["postfix.service"]; after = ["postfix.service"]; startLimitIntervalSec = 10; startLimitBurst = 5; serviceConfig.Type = "oneshot"; script = '' ${pkgs.systemd}/bin/systemctl reload postfix ''; wantedBy = ["multi-user.target"]; }; services.mailman = { enable = true; # We use caddy instead of nginx #serve.enable = true; hyperkitty.enable = true; webHosts = ["list.pub.solar"]; siteOwner = "admins@pub.solar"; }; # TODO add django-keycloak as auth provider # https://django-keycloak.readthedocs.io/en/latest/ ## Extend settings.py directly since this can't be done via JSON ## settings (services.mailman.webSettings) #environment.etc."mailman3/settings.py".text = '' # INSTALLED_APPS.extend([ # "allauth.socialaccount.providers.github", # "allauth.socialaccount.providers.gitlab" # ]) #''; systemd.services.mailman-uwsgi = let uwsgiConfig.uwsgi = { type = "normal"; plugins = ["python3"]; home = webEnv; manage-script-name = true; mount = "/=mailman_web.wsgi:application"; http = "127.0.0.1:18507"; }; uwsgiConfigFile = pkgs.writeText "uwsgi-mailman.json" (builtins.toJSON uwsgiConfig); in { wantedBy = ["multi-user.target"]; after = ["postgresql.service"]; requires = ["mailman-web-setup.service" "postgresql.service"]; restartTriggers = [config.environment.etc."mailman3/settings.py".source]; serviceConfig = { # Since the mailman-web settings.py obstinately creates a logs # dir in the cwd, change to the (writable) runtime directory before # starting uwsgi. ExecStart = "${pkgs.coreutils}/bin/env -C $RUNTIME_DIRECTORY ${pkgs.uwsgi.override {plugins = ["python3"];}}/bin/uwsgi --json ${uwsgiConfigFile}"; User = "mailman-web"; Group = "mailman"; RuntimeDirectory = "mailman-uwsgi"; }; }; }