1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.mailhog;
9
10 args = lib.concatStringsSep " " (
11 [
12 "-api-bind-addr :${toString cfg.apiPort}"
13 "-smtp-bind-addr :${toString cfg.smtpPort}"
14 "-ui-bind-addr :${toString cfg.uiPort}"
15 "-storage ${cfg.storage}"
16 ]
17 ++ lib.optional (cfg.storage == "maildir") "-maildir-path $STATE_DIRECTORY"
18 ++ cfg.extraArgs
19 );
20
21 mhsendmail = pkgs.writeShellScriptBin "mailhog-sendmail" ''
22 exec ${lib.getExe pkgs.mailhog} sendmail $@
23 '';
24in
25{
26 ###### interface
27
28 imports = [
29 (lib.mkRemovedOptionModule [
30 "services"
31 "mailhog"
32 "user"
33 ] "")
34 ];
35
36 options = {
37
38 services.mailhog = {
39 enable = lib.mkEnableOption "MailHog, web and API based SMTP testing";
40
41 setSendmail = lib.mkEnableOption "set the system sendmail to mailhogs's" // {
42 default = true;
43 };
44
45 storage = lib.mkOption {
46 type = lib.types.enum [
47 "maildir"
48 "memory"
49 ];
50 default = "memory";
51 description = "Store mails on disk or in memory.";
52 };
53
54 apiPort = lib.mkOption {
55 type = lib.types.port;
56 default = 8025;
57 description = "Port on which the API endpoint will listen.";
58 };
59
60 smtpPort = lib.mkOption {
61 type = lib.types.port;
62 default = 1025;
63 description = "Port on which the SMTP endpoint will listen.";
64 };
65
66 uiPort = lib.mkOption {
67 type = lib.types.port;
68 default = 8025;
69 description = "Port on which the HTTP UI will listen.";
70 };
71
72 extraArgs = lib.mkOption {
73 type = lib.types.listOf lib.types.str;
74 default = [ ];
75 description = "List of additional arguments to pass to the MailHog process.";
76 };
77 };
78 };
79
80 ###### implementation
81
82 config = lib.mkIf cfg.enable {
83
84 systemd.services.mailhog = {
85 description = "MailHog - Web and API based SMTP testing";
86 after = [ "network.target" ];
87 wantedBy = [ "multi-user.target" ];
88 serviceConfig = {
89 Type = "exec";
90 ExecStart = "${lib.getExe pkgs.mailhog} ${args}";
91 DynamicUser = true;
92 Restart = "on-failure";
93 StateDirectory = "mailhog";
94 };
95 };
96
97 services.mail.sendmailSetuidWrapper = lib.mkIf cfg.setSendmail {
98 program = "sendmail";
99 source = lib.getExe mhsendmail;
100 # Communication happens through the network, no data is written to disk
101 owner = "nobody";
102 group = "nogroup";
103 };
104 };
105
106 meta.maintainers = with lib.maintainers; [ RTUnreal ];
107}