at master 4.5 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.dragonflydb; 9 dragonflydb = pkgs.dragonflydb; 10 11 settings = { 12 port = cfg.port; 13 dir = "/var/lib/dragonflydb"; 14 keys_output_limit = cfg.keysOutputLimit; 15 } 16 // (lib.optionalAttrs (cfg.bind != null) { bind = cfg.bind; }) 17 // (lib.optionalAttrs (cfg.requirePass != null) { requirepass = cfg.requirePass; }) 18 // (lib.optionalAttrs (cfg.maxMemory != null) { maxmemory = cfg.maxMemory; }) 19 // (lib.optionalAttrs (cfg.memcachePort != null) { memcache_port = cfg.memcachePort; }) 20 // (lib.optionalAttrs (cfg.dbNum != null) { dbnum = cfg.dbNum; }) 21 // (lib.optionalAttrs (cfg.cacheMode != null) { cache_mode = cfg.cacheMode; }); 22in 23{ 24 25 ###### interface 26 27 options = { 28 services.dragonflydb = { 29 enable = lib.mkEnableOption "DragonflyDB"; 30 31 user = lib.mkOption { 32 type = lib.types.str; 33 default = "dragonfly"; 34 description = "The user to run DragonflyDB as"; 35 }; 36 37 port = lib.mkOption { 38 type = lib.types.port; 39 default = 6379; 40 description = "The TCP port to accept connections."; 41 }; 42 43 bind = lib.mkOption { 44 type = with lib.types; nullOr str; 45 default = "127.0.0.1"; 46 description = '' 47 The IP interface to bind to. 48 `null` means "all interfaces". 49 ''; 50 }; 51 52 requirePass = lib.mkOption { 53 type = with lib.types; nullOr str; 54 default = null; 55 description = "Password for database"; 56 example = "letmein!"; 57 }; 58 59 maxMemory = lib.mkOption { 60 type = with lib.types; nullOr ints.unsigned; 61 default = null; 62 description = '' 63 The maximum amount of memory to use for storage (in bytes). 64 `null` means this will be automatically set. 65 ''; 66 }; 67 68 memcachePort = lib.mkOption { 69 type = with lib.types; nullOr port; 70 default = null; 71 description = '' 72 To enable memcached compatible API on this port. 73 `null` means disabled. 74 ''; 75 }; 76 77 keysOutputLimit = lib.mkOption { 78 type = lib.types.ints.unsigned; 79 default = 8192; 80 description = '' 81 Maximum number of returned keys in keys command. 82 `keys` is a dangerous command. 83 We truncate its result to avoid blowup in memory when fetching too many keys. 84 ''; 85 }; 86 87 dbNum = lib.mkOption { 88 type = with lib.types; nullOr ints.unsigned; 89 default = null; 90 description = "Maximum number of supported databases for `select`"; 91 }; 92 93 cacheMode = lib.mkOption { 94 type = with lib.types; nullOr bool; 95 default = null; 96 description = '' 97 Once this mode is on, Dragonfly will evict items least likely to be stumbled 98 upon in the future but only when it is near maxmemory limit. 99 ''; 100 }; 101 }; 102 }; 103 104 ###### implementation 105 106 config = lib.mkIf config.services.dragonflydb.enable { 107 108 users.users = lib.optionalAttrs (cfg.user == "dragonfly") { 109 dragonfly.description = "DragonflyDB server user"; 110 dragonfly.isSystemUser = true; 111 dragonfly.group = "dragonfly"; 112 }; 113 users.groups = lib.optionalAttrs (cfg.user == "dragonfly") { dragonfly = { }; }; 114 115 environment.systemPackages = [ dragonflydb ]; 116 117 systemd.services.dragonflydb = { 118 description = "DragonflyDB server"; 119 120 wantedBy = [ "multi-user.target" ]; 121 after = [ "network.target" ]; 122 123 serviceConfig = { 124 ExecStart = "${dragonflydb}/bin/dragonfly --alsologtostderr ${ 125 lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "--${n} ${lib.escapeShellArg v}") settings) 126 }"; 127 128 User = cfg.user; 129 130 # Filesystem access 131 ReadWritePaths = [ settings.dir ]; 132 StateDirectory = "dragonflydb"; 133 StateDirectoryMode = "0700"; 134 # Process Properties 135 LimitMEMLOCK = "infinity"; 136 # Caps 137 CapabilityBoundingSet = ""; 138 NoNewPrivileges = true; 139 # Sandboxing 140 ProtectSystem = "strict"; 141 ProtectHome = true; 142 PrivateTmp = true; 143 PrivateDevices = true; 144 ProtectKernelTunables = true; 145 ProtectKernelModules = true; 146 ProtectControlGroups = true; 147 LockPersonality = true; 148 RestrictAddressFamilies = [ 149 "AF_INET" 150 "AF_INET6" 151 ]; 152 RestrictRealtime = true; 153 PrivateMounts = true; 154 MemoryDenyWriteExecute = true; 155 }; 156 }; 157 }; 158}