lol
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 23.11-beta 321 lines 11 kB view raw
1{ config, lib, pkgs, ... }: 2 3let 4 inherit (lib) mkOption types mdDoc literalExpression; 5 6 cfg = config.services.hedgedoc; 7 8 # 21.03 will not be an official release - it was instead 21.05. This 9 # versionAtLeast statement remains set to 21.03 for backwards compatibility. 10 # See https://github.com/NixOS/nixpkgs/pull/108899 and 11 # https://github.com/NixOS/rfcs/blob/master/rfcs/0080-nixos-release-schedule.md. 12 name = if lib.versionAtLeast config.system.stateVersion "21.03" then 13 "hedgedoc" 14 else 15 "codimd"; 16 17 settingsFormat = pkgs.formats.json { }; 18in 19{ 20 meta.maintainers = with lib.maintainers; [ SuperSandro2000 h7x4 ]; 21 22 imports = [ 23 (lib.mkRenamedOptionModule [ "services" "codimd" ] [ "services" "hedgedoc" ]) 24 (lib.mkRenamedOptionModule [ "services" "hedgedoc" "configuration" ] [ "services" "hedgedoc" "settings" ]) 25 (lib.mkRenamedOptionModule [ "services" "hedgedoc" "groups" ] [ "users" "users" "hedgedoc" "extraGroups" ]) 26 (lib.mkRemovedOptionModule [ "services" "hedgedoc" "workDir" ] '' 27 This option has been removed in favor of systemd managing the state directory. 28 29 If you have set this option without specifying `services.settings.uploadsDir`, 30 please move these files to `/var/lib/hedgedoc/uploads`, or set the option to point 31 at the correct location. 32 '') 33 ]; 34 35 options.services.hedgedoc = { 36 package = lib.mkPackageOptionMD pkgs "hedgedoc" { }; 37 enable = lib.mkEnableOption (mdDoc "the HedgeDoc Markdown Editor"); 38 39 settings = mkOption { 40 type = types.submodule { 41 freeformType = settingsFormat.type; 42 options = { 43 domain = mkOption { 44 type = with types; nullOr str; 45 default = null; 46 example = "hedgedoc.org"; 47 description = mdDoc '' 48 Domain to use for website. 49 50 This is useful if you are trying to run hedgedoc behind 51 a reverse proxy. 52 ''; 53 }; 54 urlPath = mkOption { 55 type = with types; nullOr str; 56 default = null; 57 example = "hedgedoc"; 58 description = mdDoc '' 59 URL path for the website. 60 61 This is useful if you are hosting hedgedoc on a path like 62 `www.example.com/hedgedoc` 63 ''; 64 }; 65 host = mkOption { 66 type = with types; nullOr str; 67 default = "localhost"; 68 description = mdDoc '' 69 Address to listen on. 70 ''; 71 }; 72 port = mkOption { 73 type = types.port; 74 default = 3000; 75 example = 80; 76 description = mdDoc '' 77 Port to listen on. 78 ''; 79 }; 80 path = mkOption { 81 type = with types; nullOr path; 82 default = null; 83 example = "/run/hedgedoc/hedgedoc.sock"; 84 description = mdDoc '' 85 Path to UNIX domain socket to listen on 86 87 ::: {.note} 88 If specified, {option}`host` and {option}`port` will be ignored. 89 ::: 90 ''; 91 }; 92 protocolUseSSL = mkOption { 93 type = types.bool; 94 default = false; 95 example = true; 96 description = mdDoc '' 97 Use `https://` for all links. 98 99 This is useful if you are trying to run hedgedoc behind 100 a reverse proxy. 101 102 ::: {.note} 103 Only applied if {option}`domain` is set. 104 ::: 105 ''; 106 }; 107 allowOrigin = mkOption { 108 type = with types; listOf str; 109 default = with cfg.settings; [ host ] ++ lib.optionals (domain != null) [ domain ]; 110 defaultText = literalExpression '' 111 with config.services.hedgedoc.settings; [ host ] ++ lib.optionals (domain != null) [ domain ] 112 ''; 113 example = [ "localhost" "hedgedoc.org" ]; 114 description = mdDoc '' 115 List of domains to whitelist. 116 ''; 117 }; 118 db = mkOption { 119 type = types.attrs; 120 default = { 121 dialect = "sqlite"; 122 storage = "/var/lib/${name}/db.sqlite"; 123 }; 124 defaultText = literalExpression '' 125 { 126 dialect = "sqlite"; 127 storage = "/var/lib/hedgedoc/db.sqlite"; 128 } 129 ''; 130 example = literalExpression '' 131 db = { 132 username = "hedgedoc"; 133 database = "hedgedoc"; 134 host = "localhost:5432"; 135 # or via socket 136 # host = "/run/postgresql"; 137 dialect = "postgresql"; 138 }; 139 ''; 140 description = mdDoc '' 141 Specify the configuration for sequelize. 142 HedgeDoc supports `mysql`, `postgres`, `sqlite` and `mssql`. 143 See <https://sequelize.readthedocs.io/en/v3/> 144 for more information. 145 146 ::: {.note} 147 The relevant parts will be overriden if you set {option}`dbURL`. 148 ::: 149 ''; 150 }; 151 useSSL = mkOption { 152 type = types.bool; 153 default = false; 154 description = mdDoc '' 155 Enable to use SSL server. 156 157 ::: {.note} 158 This will also enable {option}`protocolUseSSL`. 159 160 It will also require you to set the following: 161 162 - {option}`sslKeyPath` 163 - {option}`sslCertPath` 164 - {option}`sslCAPath` 165 - {option}`dhParamPath` 166 ::: 167 ''; 168 }; 169 uploadsPath = mkOption { 170 type = types.path; 171 default = "/var/lib/${name}/uploads"; 172 defaultText = "/var/lib/hedgedoc/uploads"; 173 description = mdDoc '' 174 Directory for storing uploaded images. 175 ''; 176 }; 177 178 # Declared because we change the default to false. 179 allowGravatar = mkOption { 180 type = types.bool; 181 default = false; 182 example = true; 183 description = mdDoc '' 184 Whether to enable [Libravatar](https://wiki.libravatar.org/) as 185 profile picture source on your instance. 186 187 Despite the naming of the setting, Hedgedoc replaced Gravatar 188 with Libravatar in [CodiMD 1.4.0](https://hedgedoc.org/releases/1.4.0/) 189 ''; 190 }; 191 }; 192 }; 193 194 description = mdDoc '' 195 HedgeDoc configuration, see 196 <https://docs.hedgedoc.org/configuration/> 197 for documentation. 198 ''; 199 }; 200 201 environmentFile = mkOption { 202 type = with types; nullOr path; 203 default = null; 204 example = "/var/lib/hedgedoc/hedgedoc.env"; 205 description = mdDoc '' 206 Environment file as defined in {manpage}`systemd.exec(5)`. 207 208 Secrets may be passed to the service without adding them to the world-readable 209 Nix store, by specifying placeholder variables as the option value in Nix and 210 setting these variables accordingly in the environment file. 211 212 ``` 213 # snippet of HedgeDoc-related config 214 services.hedgedoc.settings.dbURL = "postgres://hedgedoc:\''${DB_PASSWORD}@db-host:5432/hedgedocdb"; 215 services.hedgedoc.settings.minio.secretKey = "$MINIO_SECRET_KEY"; 216 ``` 217 218 ``` 219 # content of the environment file 220 DB_PASSWORD=verysecretdbpassword 221 MINIO_SECRET_KEY=verysecretminiokey 222 ``` 223 224 Note that this file needs to be available on the host on which 225 `HedgeDoc` is running. 226 ''; 227 }; 228 }; 229 230 config = lib.mkIf cfg.enable { 231 users.groups.${name} = { }; 232 users.users.${name} = { 233 description = "HedgeDoc service user"; 234 group = name; 235 isSystemUser = true; 236 }; 237 238 services.hedgedoc.settings = { 239 defaultNotePath = lib.mkDefault "${cfg.package}/public/default.md"; 240 docsPath = lib.mkDefault "${cfg.package}/public/docs"; 241 viewPath = lib.mkDefault "${cfg.package}/public/views"; 242 }; 243 244 systemd.services.hedgedoc = { 245 description = "HedgeDoc Service"; 246 documentation = [ "https://docs.hedgedoc.org/" ]; 247 wantedBy = [ "multi-user.target" ]; 248 after = [ "networking.target" ]; 249 preStart = 250 let 251 configFile = settingsFormat.generate "hedgedoc-config.json" { 252 production = cfg.settings; 253 }; 254 in 255 '' 256 ${pkgs.envsubst}/bin/envsubst \ 257 -o /run/${name}/config.json \ 258 -i ${configFile} 259 ${pkgs.coreutils}/bin/mkdir -p ${cfg.settings.uploadsPath} 260 ''; 261 serviceConfig = { 262 User = name; 263 Group = name; 264 265 Restart = "always"; 266 ExecStart = "${cfg.package}/bin/hedgedoc"; 267 RuntimeDirectory = [ name ]; 268 StateDirectory = [ name ]; 269 WorkingDirectory = "/run/${name}"; 270 ReadWritePaths = [ 271 "-${cfg.settings.uploadsPath}" 272 ] ++ lib.optionals (cfg.settings.db ? "storage") [ "-${cfg.settings.db.storage}" ]; 273 EnvironmentFile = lib.mkIf (cfg.environmentFile != null) [ cfg.environmentFile ]; 274 Environment = [ 275 "CMD_CONFIG_FILE=/run/${name}/config.json" 276 "NODE_ENV=production" 277 ]; 278 279 # Hardening 280 AmbientCapabilities = ""; 281 CapabilityBoundingSet = ""; 282 LockPersonality = true; 283 NoNewPrivileges = true; 284 PrivateDevices = true; 285 PrivateMounts = true; 286 PrivateTmp = true; 287 PrivateUsers = true; 288 ProcSubset = "pid"; 289 ProtectClock = true; 290 ProtectControlGroups = true; 291 ProtectHome = true; 292 ProtectHostname = true; 293 ProtectKernelLogs = true; 294 ProtectKernelModules = true; 295 ProtectKernelTunables = true; 296 ProtectProc = "invisible"; 297 ProtectSystem = "strict"; 298 RemoveIPC = true; 299 RestrictAddressFamilies = [ 300 "AF_INET" 301 "AF_INET6" 302 # Required for connecting to database sockets, 303 # and listening to unix socket at `cfg.settings.path` 304 "AF_UNIX" 305 ]; 306 RestrictNamespaces = true; 307 RestrictRealtime = true; 308 RestrictSUIDSGID = true; 309 SocketBindAllow = lib.mkIf (cfg.settings.path == null) cfg.settings.port; 310 SocketBindDeny = "any"; 311 SystemCallArchitectures = "native"; 312 SystemCallFilter = [ 313 "@system-service" 314 "~@privileged @obsolete" 315 "@pkey" 316 ]; 317 UMask = "0007"; 318 }; 319 }; 320 }; 321}