1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.memcached;
8
9 memcached = pkgs.memcached;
10
11in
12
13{
14
15 ###### interface
16
17 options = {
18
19 services.memcached = {
20 enable = mkEnableOption "Memcached";
21
22 user = mkOption {
23 type = types.str;
24 default = "memcached";
25 description = "The user to run Memcached as";
26 };
27
28 listen = mkOption {
29 type = types.str;
30 default = "127.0.0.1";
31 description = "The IP address to bind to.";
32 };
33
34 port = mkOption {
35 type = types.port;
36 default = 11211;
37 description = "The port to bind to.";
38 };
39
40 enableUnixSocket = mkEnableOption "unix socket at /run/memcached/memcached.sock";
41
42 maxMemory = mkOption {
43 type = types.ints.unsigned;
44 default = 64;
45 description = "The maximum amount of memory to use for storage, in megabytes.";
46 };
47
48 maxConnections = mkOption {
49 type = types.ints.unsigned;
50 default = 1024;
51 description = "The maximum number of simultaneous connections.";
52 };
53
54 extraOptions = mkOption {
55 type = types.listOf types.str;
56 default = [];
57 description = "A list of extra options that will be added as a suffix when running memcached.";
58 };
59 };
60
61 };
62
63 ###### implementation
64
65 config = mkIf config.services.memcached.enable {
66
67 users.users = optionalAttrs (cfg.user == "memcached") {
68 memcached.description = "Memcached server user";
69 memcached.isSystemUser = true;
70 };
71
72 environment.systemPackages = [ memcached ];
73
74 systemd.services.memcached = {
75 description = "Memcached server";
76
77 wantedBy = [ "multi-user.target" ];
78 after = [ "network.target" ];
79
80 serviceConfig = {
81 ExecStart =
82 let
83 networking = if cfg.enableUnixSocket
84 then "-s /run/memcached/memcached.sock"
85 else "-l ${cfg.listen} -p ${toString cfg.port}";
86 in "${memcached}/bin/memcached ${networking} -m ${toString cfg.maxMemory} -c ${toString cfg.maxConnections} ${concatStringsSep " " cfg.extraOptions}";
87
88 User = cfg.user;
89
90 # Filesystem access
91 ProtectSystem = "strict";
92 ProtectHome = true;
93 PrivateTmp = true;
94 PrivateDevices = true;
95 ProtectKernelTunables = true;
96 ProtectKernelModules = true;
97 ProtectControlGroups = true;
98 RuntimeDirectory = "memcached";
99 # Caps
100 CapabilityBoundingSet = "";
101 NoNewPrivileges = true;
102 # Misc.
103 LockPersonality = true;
104 RestrictRealtime = true;
105 PrivateMounts = true;
106 MemoryDenyWriteExecute = true;
107 };
108 };
109 };
110 imports = [
111 (mkRemovedOptionModule ["services" "memcached" "socket"] ''
112 This option was replaced by a fixed unix socket path at /run/memcached/memcached.sock enabled using services.memcached.enableUnixSocket.
113 '')
114 ];
115
116}