grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / search / typesense.nix
bloba44d932593e516b91b9cf5b4a865587e7944df70
1 { config, lib, pkgs, ... }: let
2   inherit
3     (lib)
4     concatMapStringsSep
5     generators
6     mkEnableOption
7     mkIf
8     mkOption
9     mkPackageOption
10     optionalString
11     types
12     ;
14   cfg = config.services.typesense;
15   settingsFormatIni = pkgs.formats.ini {
16     listToValue = concatMapStringsSep " " (generators.mkValueStringDefault { });
17     mkKeyValue = generators.mkKeyValueDefault
18       {
19         mkValueString = v:
20           if v == null then ""
21           else generators.mkValueStringDefault { } v;
22       }
23       "=";
24   };
25   configFile = settingsFormatIni.generate "typesense.ini" cfg.settings;
26 in {
27   options.services.typesense = {
28     enable = mkEnableOption "typesense";
29     package = mkPackageOption pkgs "typesense" {};
31     apiKeyFile = mkOption {
32       type = types.path;
33       description = ''
34         Sets the admin api key for typesense. Always use this option
35         instead of {option}`settings.server.api-key` to prevent the key
36         from being written to the world-readable nix store.
37       '';
38     };
40     settings = mkOption {
41       description = "Typesense configuration. Refer to [the documentation](https://typesense.org/docs/0.24.1/api/server-configuration.html) for supported values.";
42       default = {};
43       type = types.submodule {
44         freeformType = settingsFormatIni.type;
45         options.server = {
46           data-dir = mkOption {
47             type = types.str;
48             default = "/var/lib/typesense";
49             description = "Path to the directory where data will be stored on disk.";
50           };
52           api-address = mkOption {
53             type = types.str;
54             description = "Address to which Typesense API service binds.";
55           };
57           api-port = mkOption {
58             type = types.port;
59             default = 8108;
60             description = "Port on which the Typesense API service listens.";
61           };
62         };
63       };
64     };
65   };
67   config = mkIf cfg.enable {
68     systemd.services.typesense = {
69       description = "Typesense search engine";
70       wantedBy = [ "multi-user.target" ];
71       after = [ "network.target" ];
73       script = ''
74         export TYPESENSE_API_KEY=$(cat ${cfg.apiKeyFile})
75         exec ${cfg.package}/bin/typesense-server --config ${configFile}
76       '';
78       serviceConfig = {
79         Restart = "on-failure";
80         DynamicUser = true;
81         User = "typesense";
82         Group = "typesense";
84         StateDirectory = "typesense";
85         StateDirectoryMode = "0750";
87         # Hardening
88         CapabilityBoundingSet = "";
89         LockPersonality = true;
90         # MemoryDenyWriteExecute = true; needed since 0.25.1
91         NoNewPrivileges = true;
92         PrivateUsers = true;
93         PrivateTmp = true;
94         PrivateDevices = true;
95         PrivateMounts = true;
96         ProtectClock = true;
97         ProtectControlGroups = true;
98         ProtectHome = true;
99         ProtectHostname = true;
100         ProtectKernelLogs = true;
101         ProtectKernelModules = true;
102         ProtectKernelTunables = true;
103         ProtectProc = "invisible";
104         ProcSubset = "pid";
105         ProtectSystem = "strict";
106         RemoveIPC = true;
107         RestrictAddressFamilies = [
108           "AF_INET"
109           "AF_INET6"
110           "AF_UNIX"
111         ];
112         RestrictNamespaces = true;
113         RestrictRealtime = true;
114         RestrictSUIDSGID = true;
115         SystemCallArchitectures = "native";
116         SystemCallFilter = [
117           "@system-service"
118           "~@privileged"
119         ];
120         UMask = "0077";
121       };
122     };
123   };