at master 5.5 kB view raw
1{ 2 config, 3 options, 4 pkgs, 5 lib, 6 ... 7}: 8let 9 cfg = config.services.memos; 10 opt = options.services.memos; 11 envFileFormat = pkgs.formats.keyValue { }; 12in 13{ 14 options.services.memos = { 15 enable = lib.mkEnableOption "Memos note-taking"; 16 package = lib.mkPackageOption pkgs "Memos" { 17 default = "memos"; 18 }; 19 20 openFirewall = lib.mkEnableOption "opening the ports in the firewall"; 21 22 user = lib.mkOption { 23 type = lib.types.str; 24 description = '' 25 The user to run Memos as. 26 27 ::: {.note} 28 If changing the default value, **you** are responsible of creating the corresponding user with [{option}`users.users`](#opt-users.users). 29 ::: 30 ''; 31 default = "memos"; 32 }; 33 34 group = lib.mkOption { 35 type = lib.types.str; 36 description = '' 37 The group to run Memos as. 38 39 ::: {.note} 40 If changing the default value, **you** are responsible of creating the corresponding group with [{option}`users.groups`](#opt-users.groups). 41 ::: 42 ''; 43 default = "memos"; 44 }; 45 46 dataDir = lib.mkOption { 47 default = "/var/lib/memos/"; 48 type = lib.types.path; 49 description = '' 50 Specifies the directory where Memos will store its data. 51 52 ::: {.note} 53 It will be automatically created with the permissions of [{option}`services.memos.user`](#opt-services.memos.user) and [{option}`services.memos.group`](#opt-services.memos.group). 54 ::: 55 ''; 56 }; 57 58 settings = lib.mkOption { 59 type = envFileFormat.type; 60 description = '' 61 The environment variables to configure Memos. 62 63 ::: {.note} 64 At time of writing, there is no clear documentation about possible values. 65 It's possible to convert CLI flags into these variables. 66 Example : CLI flag "--unix-sock" converts to {env}`MEMOS_UNIX_SOCK`. 67 ::: 68 ''; 69 default = { 70 MEMOS_MODE = "prod"; 71 MEMOS_ADDR = "127.0.0.1"; 72 MEMOS_PORT = "5230"; 73 MEMOS_DATA = cfg.dataDir; 74 MEMOS_DRIVER = "sqlite"; 75 MEMOS_INSTANCE_URL = "http://localhost:5230"; 76 }; 77 defaultText = lib.literalExpression '' 78 { 79 MEMOS_MODE = "prod"; 80 MEMOS_ADDR = "127.0.0.1"; 81 MEMOS_PORT = "5230"; 82 MEMOS_DATA = config.${opt.dataDir}; 83 MEMOS_DRIVER = "sqlite"; 84 MEMOS_INSTANCE_URL = "http://localhost:5230"; 85 } 86 ''; 87 }; 88 89 environmentFile = lib.mkOption { 90 type = lib.types.path; 91 description = '' 92 The environment file to use when starting Memos. 93 94 ::: {.note} 95 By default, generated from [](opt-${opt.settings}). 96 ::: 97 ''; 98 example = "/var/lib/memos/memos.env"; 99 default = envFileFormat.generate "memos.env" cfg.settings; 100 defaultText = lib.literalMD '' 101 generated from {option}`${opt.settings}` 102 ''; 103 }; 104 }; 105 106 config = lib.mkIf cfg.enable { 107 users.users = lib.mkIf (cfg.user == "memos") { 108 ${cfg.user} = { 109 description = lib.mkDefault "Memos service user"; 110 isSystemUser = true; 111 group = cfg.group; 112 }; 113 }; 114 115 users.groups = lib.mkIf (cfg.group == "memos") { 116 ${cfg.group} = { }; 117 }; 118 119 networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ 120 cfg.port 121 ]; 122 123 systemd.tmpfiles.settings."10-memos" = { 124 "${cfg.dataDir}" = { 125 d = { 126 mode = "0750"; 127 user = cfg.user; 128 group = cfg.group; 129 }; 130 }; 131 }; 132 133 systemd.services.memos = { 134 wantedBy = [ "multi-user.target" ]; 135 after = [ "network.target" ]; 136 wants = [ "network.target" ]; 137 description = "Memos, a privacy-first, lightweight note-taking solution"; 138 serviceConfig = { 139 User = cfg.user; 140 Group = cfg.group; 141 Type = "simple"; 142 RestartSec = 60; 143 LimitNOFILE = 65536; 144 NoNewPrivileges = true; 145 LockPersonality = true; 146 RemoveIPC = true; 147 ReadWritePaths = [ 148 cfg.dataDir 149 ]; 150 ProtectSystem = "strict"; 151 PrivateUsers = true; 152 ProtectHome = true; 153 PrivateTmp = true; 154 PrivateDevices = true; 155 ProtectHostname = true; 156 ProtectClock = true; 157 UMask = "0077"; 158 ProtectKernelTunables = true; 159 ProtectKernelModules = true; 160 ProtectControlGroups = true; 161 ProtectProc = "invisible"; 162 SystemCallFilter = [ 163 " " # This is needed to clear the SystemCallFilter existing definitions 164 "~@reboot" 165 "~@swap" 166 "~@obsolete" 167 "~@mount" 168 "~@module" 169 "~@debug" 170 "~@cpu-emulation" 171 "~@clock" 172 "~@raw-io" 173 "~@privileged" 174 "~@resources" 175 ]; 176 CapabilityBoundingSet = [ 177 " " # Reset all capabilities to an empty set 178 ]; 179 RestrictAddressFamilies = [ 180 " " # This is needed to clear the RestrictAddressFamilies existing definitions 181 "none" # Remove all addresses families 182 "AF_UNIX" 183 "AF_INET" 184 "AF_INET6" 185 ]; 186 DevicePolicy = "closed"; 187 ProtectKernelLogs = true; 188 SystemCallArchitectures = "native"; 189 RestrictNamespaces = true; 190 RestrictRealtime = true; 191 RestrictSUIDSGID = true; 192 EnvironmentFile = cfg.environmentFile; 193 ExecStart = lib.getExe cfg.package; 194 }; 195 }; 196 }; 197 198 meta.maintainers = [ lib.maintainers.m0ustach3 ]; 199}