at master 4.1 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.ntfy-sh; 9 10 settingsFormat = pkgs.formats.yaml { }; 11in 12 13{ 14 options.services.ntfy-sh = { 15 enable = lib.mkEnableOption "[ntfy-sh](https://ntfy.sh), a push notification service"; 16 17 package = lib.mkPackageOption pkgs "ntfy-sh" { }; 18 19 user = lib.mkOption { 20 default = "ntfy-sh"; 21 type = lib.types.str; 22 description = "User the ntfy-sh server runs under."; 23 }; 24 25 group = lib.mkOption { 26 default = "ntfy-sh"; 27 type = lib.types.str; 28 description = "Primary group of ntfy-sh user."; 29 }; 30 31 settings = lib.mkOption { 32 type = lib.types.submodule { 33 freeformType = settingsFormat.type; 34 options = { 35 base-url = lib.mkOption { 36 type = lib.types.str; 37 example = "https://ntfy.example"; 38 description = '' 39 Public facing base URL of the service 40 41 This setting is required for any of the following features: 42 - attachments (to return a download URL) 43 - e-mail sending (for the topic URL in the email footer) 44 - iOS push notifications for self-hosted servers 45 (to calculate the Firebase poll_request topic) 46 - Matrix Push Gateway (to validate that the pushkey is correct) 47 ''; 48 }; 49 }; 50 }; 51 52 default = { }; 53 54 example = lib.literalExpression '' 55 { 56 listen-http = ":8080"; 57 } 58 ''; 59 60 description = '' 61 Configuration for ntfy.sh, supported values are [here](https://ntfy.sh/docs/config/#config-options). 62 ''; 63 }; 64 65 environmentFile = lib.mkOption { 66 type = lib.types.nullOr lib.types.path; 67 default = null; 68 example = "/run/secrets/ntfy"; 69 description = '' 70 Path to a file containing extra ntfy environment variables in the systemd `EnvironmentFile` 71 format. Refer to the [documentation](https://docs.ntfy.sh/config/) for config options. 72 73 This can be used to pass secrets such as creating declarative users or token without putting them in the Nix store. 74 ''; 75 }; 76 }; 77 78 config = 79 let 80 configuration = settingsFormat.generate "server.yml" cfg.settings; 81 in 82 lib.mkIf cfg.enable { 83 # to configure access control via the cli 84 environment = { 85 etc."ntfy/server.yml".source = configuration; 86 systemPackages = [ cfg.package ]; 87 }; 88 89 services.ntfy-sh.settings = { 90 auth-file = lib.mkDefault "/var/lib/ntfy-sh/user.db"; 91 listen-http = lib.mkDefault "127.0.0.1:2586"; 92 attachment-cache-dir = lib.mkDefault "/var/lib/ntfy-sh/attachments"; 93 cache-file = lib.mkDefault "/var/lib/ntfy-sh/cache-file.db"; 94 }; 95 96 systemd.services.ntfy-sh = { 97 description = "Push notifications server"; 98 99 wantedBy = [ "multi-user.target" ]; 100 after = [ "network.target" ]; 101 102 serviceConfig = { 103 ExecStart = "${cfg.package}/bin/ntfy serve -c ${configuration}"; 104 User = cfg.user; 105 StateDirectory = "ntfy-sh"; 106 107 DynamicUser = true; 108 AmbientCapabilities = "CAP_NET_BIND_SERVICE"; 109 PrivateTmp = true; 110 NoNewPrivileges = true; 111 CapabilityBoundingSet = "CAP_NET_BIND_SERVICE"; 112 ProtectSystem = "full"; 113 ProtectKernelTunables = true; 114 ProtectKernelModules = true; 115 ProtectKernelLogs = true; 116 ProtectControlGroups = true; 117 PrivateDevices = true; 118 RestrictSUIDSGID = true; 119 RestrictNamespaces = true; 120 RestrictRealtime = true; 121 MemoryDenyWriteExecute = true; 122 # Upstream Recommendation 123 LimitNOFILE = 20500; 124 EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; 125 }; 126 }; 127 128 users.groups = lib.optionalAttrs (cfg.group == "ntfy-sh") { 129 ntfy-sh = { }; 130 }; 131 132 users.users = lib.optionalAttrs (cfg.user == "ntfy-sh") { 133 ntfy-sh = { 134 isSystemUser = true; 135 group = cfg.group; 136 }; 137 }; 138 }; 139}