1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7let
8 cfg = config.services.uptime-kuma;
9in
10{
11
12 meta.maintainers = [ lib.maintainers.julienmalka ];
13
14 options = {
15 services.uptime-kuma = {
16 enable = lib.mkEnableOption "Uptime Kuma, this assumes a reverse proxy to be set";
17
18 package = lib.mkPackageOption pkgs "uptime-kuma" { };
19
20 appriseSupport = lib.mkEnableOption "apprise support for notifications";
21
22 settings = lib.mkOption {
23 type = lib.types.submodule { freeformType = with lib.types; attrsOf str; };
24 default = { };
25 example = {
26 PORT = "4000";
27 NODE_EXTRA_CA_CERTS = lib.literalExpression "config.security.pki.caBundle";
28 };
29 description = ''
30 Additional configuration for Uptime Kuma, see
31 <https://github.com/louislam/uptime-kuma/wiki/Environment-Variables>
32 for supported values.
33 '';
34 };
35 };
36 };
37
38 config = lib.mkIf cfg.enable {
39
40 services.uptime-kuma.settings = {
41 DATA_DIR = "/var/lib/uptime-kuma/";
42 NODE_ENV = lib.mkDefault "production";
43 HOST = lib.mkDefault "127.0.0.1";
44 PORT = lib.mkDefault "3001";
45 };
46
47 systemd.services.uptime-kuma = {
48 description = "Uptime Kuma";
49 after = [ "network.target" ];
50 wantedBy = [ "multi-user.target" ];
51 environment = cfg.settings;
52 path = with pkgs; [ unixtools.ping ] ++ lib.optional cfg.appriseSupport apprise;
53 serviceConfig = {
54 Type = "simple";
55 StateDirectory = "uptime-kuma";
56 DynamicUser = true;
57 ExecStart = "${cfg.package}/bin/uptime-kuma-server";
58 Restart = "on-failure";
59 AmbientCapabilities = "";
60 CapabilityBoundingSet = "";
61 LockPersonality = true;
62 MemoryDenyWriteExecute = false; # enabling it breaks execution
63 NoNewPrivileges = true;
64 PrivateDevices = true;
65 PrivateMounts = true;
66 PrivateTmp = true;
67 ProtectClock = true;
68 ProtectControlGroups = true;
69 ProtectHome = true;
70 ProtectHostname = true;
71 ProtectKernelLogs = true;
72 ProtectKernelModules = true;
73 ProtectKernelTunables = true;
74 ProtectProc = "noaccess";
75 ProtectSystem = "strict";
76 RemoveIPC = true;
77 RestrictAddressFamilies = [
78 "AF_INET"
79 "AF_INET6"
80 "AF_UNIX"
81 "AF_NETLINK"
82 ];
83 RestrictNamespaces = true;
84 RestrictRealtime = true;
85 RestrictSUIDSGID = true;
86 SystemCallArchitectures = "native";
87 UMask = 27;
88 };
89 };
90 };
91}