12 cfg = config.services.nats;
14 format = pkgs.formats.json { };
16 configFile = format.generate "nats.conf" cfg.settings;
20 pkgs.runCommand "validate-nats-conf"
22 nativeBuildInputs = [ pkgs.nats-server ];
25 nats-server --config "${configFile}" -t
26 ln -s "${configFile}" "$out"
35 enable = mkEnableOption "NATS messaging system";
40 description = "User account under which NATS runs.";
46 description = "Group under which NATS runs.";
49 serverName = mkOption {
54 Name of the NATS server, must be unique if clustered.
58 jetstream = mkEnableOption "JetStream";
64 Port on which to listen.
69 default = "/var/lib/nats";
72 The NATS data directory. Only used if JetStream is enabled, for
73 storing stream metadata and messages.
75 If left as the default value this directory will automatically be
76 created before the NATS server starts, otherwise the sysadmin is
77 responsible for ensuring the directory exists with appropriate
78 ownership and permissions.
85 example = literalExpression ''
94 Declarative NATS configuration. See the
96 NATS documentation](https://docs.nats.io/nats-server/configuration) for a list of options.
104 config = mkIf cfg.enable {
105 services.nats.settings = {
106 server_name = cfg.serverName;
108 jetstream = optionalAttrs cfg.jetstream { store_dir = cfg.dataDir; };
111 systemd.services.nats = {
112 description = "NATS messaging system";
113 wantedBy = [ "multi-user.target" ];
114 after = [ "network.target" ];
116 serviceConfig = mkMerge [
117 (mkIf (cfg.dataDir == "/var/lib/nats") {
118 StateDirectory = "nats";
119 StateDirectoryMode = "0750";
123 ExecStart = "${pkgs.nats-server}/bin/nats-server -c ${validateConfig configFile}";
124 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
125 ExecStop = "${pkgs.coreutils}/bin/kill -SIGINT $MAINPID";
126 Restart = "on-failure";
132 CapabilityBoundingSet = "";
133 LimitNOFILE = 800000; # JetStream requires 2 FDs open per stream.
134 LockPersonality = true;
135 MemoryDenyWriteExecute = true;
136 NoNewPrivileges = true;
137 PrivateDevices = true;
142 ProtectControlGroups = true;
144 ProtectHostname = true;
145 ProtectKernelLogs = true;
146 ProtectKernelModules = true;
147 ProtectKernelTunables = true;
148 ProtectProc = "invisible";
149 ProtectSystem = "strict";
151 ReadWritePaths = [ cfg.dataDir ];
152 RestrictAddressFamilies = [
156 RestrictNamespaces = true;
157 RestrictRealtime = true;
158 RestrictSUIDSGID = true;
168 users.users = mkIf (cfg.user == "nats") {
170 description = "NATS daemon user";
177 users.groups = mkIf (cfg.group == "nats") { nats = { }; };