1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8with lib;
9
10let
11 cfg = config.services.molly-brown;
12 settingsFormat = pkgs.formats.toml { };
13 configFile = settingsFormat.generate "molly-brown.toml" cfg.settings;
14in
15{
16
17 options.services.molly-brown = {
18
19 enable = mkEnableOption "Molly-Brown Gemini server";
20
21 port = mkOption {
22 default = 1965;
23 type = types.port;
24 description = ''
25 TCP port for molly-brown to bind to.
26 '';
27 };
28
29 hostName = mkOption {
30 type = types.str;
31 default = config.networking.hostName;
32 defaultText = literalExpression "config.networking.hostName";
33 description = ''
34 The hostname to respond to requests for. Requests for URLs with
35 other hosts will result in a status 53 (PROXY REQUEST REFUSED)
36 response.
37 '';
38 };
39
40 certPath = mkOption {
41 type = types.path;
42 example = "/var/lib/acme/example.com/cert.pem";
43 description = ''
44 Path to TLS certificate. An ACME certificate and key may be
45 shared with an HTTP server, but only if molly-brown has
46 permissions allowing it to read such keys.
47
48 As an example:
49 ```
50 systemd.services.molly-brown.serviceConfig.SupplementaryGroups =
51 [ config.security.acme.certs."example.com".group ];
52 ```
53 '';
54 };
55
56 keyPath = mkOption {
57 type = types.path;
58 example = "/var/lib/acme/example.com/key.pem";
59 description = "Path to TLS key. See {option}`CertPath`.";
60 };
61
62 docBase = mkOption {
63 type = types.path;
64 example = "/var/lib/molly-brown";
65 description = "Base directory for Gemini content.";
66 };
67
68 settings = mkOption {
69 inherit (settingsFormat) type;
70 default = { };
71 description = ''
72 molly-brown configuration. Refer to
73 <https://tildegit.org/solderpunk/molly-brown/src/branch/master/example.conf>
74 for details on supported values.
75 '';
76 };
77
78 };
79
80 config = mkIf cfg.enable {
81
82 services.molly-brown.settings =
83 let
84 logDir = "/var/log/molly-brown";
85 in
86 {
87 Port = cfg.port;
88 Hostname = cfg.hostName;
89 CertPath = cfg.certPath;
90 KeyPath = cfg.keyPath;
91 DocBase = cfg.docBase;
92 AccessLog = "${logDir}/access.log";
93 ErrorLog = "${logDir}/error.log";
94 };
95
96 systemd.services.molly-brown = {
97 description = "Molly Brown gemini server";
98 after = [ "network.target" ];
99 wantedBy = [ "multi-user.target" ];
100 serviceConfig = {
101 DynamicUser = true;
102 LogsDirectory = "molly-brown";
103 ExecStart = "${pkgs.molly-brown}/bin/molly-brown -c ${configFile}";
104 Restart = "always";
105 };
106 };
107
108 };
109
110}