python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / networking / searx.nix
blob214b6c6a787a5d9c4ec4b90873d002556e05ffda
1 { options, config, lib, pkgs, ... }:
3 with lib;
5 let
6   runDir = "/run/searx";
8   cfg = config.services.searx;
10   settingsFile = pkgs.writeText "settings.yml"
11     (builtins.toJSON cfg.settings);
13   generateConfig = ''
14     cd ${runDir}
16     # write NixOS settings as JSON
17     (
18       umask 077
19       cp --no-preserve=mode ${settingsFile} settings.yml
20     )
22     # substitute environment variables
23     env -0 | while IFS='=' read -r -d ''' n v; do
24       sed "s#@$n@#$v#g" -i settings.yml
25     done
26   '';
28   settingType = with types; (oneOf
29     [ bool int float str
30       (listOf settingType)
31       (attrsOf settingType)
32     ]) // { description = "JSON value"; };
38   imports = [
39     (mkRenamedOptionModule
40       [ "services" "searx" "configFile" ]
41       [ "services" "searx" "settingsFile" ])
42   ];
44   ###### interface
46   options = {
48     services.searx = {
50       enable = mkOption {
51         type = types.bool;
52         default = false;
53         relatedPackages = [ "searx" ];
54         description = lib.mdDoc "Whether to enable Searx, the meta search engine.";
55       };
57       environmentFile = mkOption {
58         type = types.nullOr types.path;
59         default = null;
60         description = lib.mdDoc ''
61           Environment file (see `systemd.exec(5)`
62           "EnvironmentFile=" section for the syntax) to define variables for
63           Searx. This option can be used to safely include secret keys into the
64           Searx configuration.
65         '';
66       };
68       settings = mkOption {
69         type = types.attrsOf settingType;
70         default = { };
71         example = literalExpression ''
72           { server.port = 8080;
73             server.bind_address = "0.0.0.0";
74             server.secret_key = "@SEARX_SECRET_KEY@";
76             engines = lib.singleton
77               { name = "wolframalpha";
78                 shortcut = "wa";
79                 api_key = "@WOLFRAM_API_KEY@";
80                 engine = "wolframalpha_api";
81               };
82           }
83         '';
84         description = lib.mdDoc ''
85           Searx settings. These will be merged with (taking precedence over)
86           the default configuration. It's also possible to refer to
87           environment variables
88           (defined in [](#opt-services.searx.environmentFile))
89           using the syntax `@VARIABLE_NAME@`.
91           ::: {.note}
92           For available settings, see the Searx
93           [docs](https://searx.github.io/searx/admin/settings.html).
94           :::
95         '';
96       };
98       settingsFile = mkOption {
99         type = types.path;
100         default = "${runDir}/settings.yml";
101         description = lib.mdDoc ''
102           The path of the Searx server settings.yml file. If no file is
103           specified, a default file is used (default config file has debug mode
104           enabled). Note: setting this options overrides
105           [](#opt-services.searx.settings).
107           ::: {.warning}
108           This file, along with any secret key it contains, will be copied
109           into the world-readable Nix store.
110           :::
111         '';
112       };
114       package = mkOption {
115         type = types.package;
116         default = pkgs.searx;
117         defaultText = literalExpression "pkgs.searx";
118         description = lib.mdDoc "searx package to use.";
119       };
121       runInUwsgi = mkOption {
122         type = types.bool;
123         default = false;
124         description = lib.mdDoc ''
125           Whether to run searx in uWSGI as a "vassal", instead of using its
126           built-in HTTP server. This is the recommended mode for public or
127           large instances, but is unecessary for LAN or local-only use.
129           ::: {.warning}
130           The built-in HTTP server logs all queries by default.
131           :::
132         '';
133       };
135       uwsgiConfig = mkOption {
136         type = options.services.uwsgi.instance.type;
137         default = { http = ":8080"; };
138         example = literalExpression ''
139           {
140             disable-logging = true;
141             http = ":8080";                   # serve via HTTP...
142             socket = "/run/searx/searx.sock"; # ...or UNIX socket
143             chmod-socket = "660";             # allow the searx group to read/write to the socket
144           }
145         '';
146         description = lib.mdDoc ''
147           Additional configuration of the uWSGI vassal running searx. It
148           should notably specify on which interfaces and ports the vassal
149           should listen.
150         '';
151       };
153     };
155   };
158   ###### implementation
160   config = mkIf cfg.enable {
161     environment.systemPackages = [ cfg.package ];
163     users.users.searx =
164       { description = "Searx daemon user";
165         group = "searx";
166         isSystemUser = true;
167       };
169     users.groups.searx = { };
171     systemd.services.searx-init = {
172       description = "Initialise Searx settings";
173       serviceConfig = {
174         Type = "oneshot";
175         RemainAfterExit = true;
176         User = "searx";
177         RuntimeDirectory = "searx";
178         RuntimeDirectoryMode = "750";
179       } // optionalAttrs (cfg.environmentFile != null)
180         { EnvironmentFile = builtins.toPath cfg.environmentFile; };
181       script = generateConfig;
182     };
184     systemd.services.searx = mkIf (!cfg.runInUwsgi) {
185       description = "Searx server, the meta search engine.";
186       wantedBy = [ "network.target" "multi-user.target" ];
187       requires = [ "searx-init.service" ];
188       after = [ "searx-init.service" ];
189       serviceConfig = {
190         User  = "searx";
191         Group = "searx";
192         ExecStart = "${cfg.package}/bin/searx-run";
193       } // optionalAttrs (cfg.environmentFile != null)
194         { EnvironmentFile = builtins.toPath cfg.environmentFile; };
195       environment = {
196         SEARX_SETTINGS_PATH = cfg.settingsFile;
197         SEARXNG_SETTINGS_PATH = cfg.settingsFile;
198       };
199     };
201     systemd.services.uwsgi = mkIf (cfg.runInUwsgi)
202       { requires = [ "searx-init.service" ];
203         after = [ "searx-init.service" ];
204       };
206     services.searx.settings = {
207       # merge NixOS settings with defaults settings.yml
208       use_default_settings = mkDefault true;
209     };
211     services.uwsgi = mkIf (cfg.runInUwsgi) {
212       enable = true;
213       plugins = [ "python3" ];
215       instance.type = "emperor";
216       instance.vassals.searx = {
217         type = "normal";
218         strict = true;
219         immediate-uid = "searx";
220         immediate-gid = "searx";
221         lazy-apps = true;
222         enable-threads = true;
223         module = "searx.webapp";
224         env = [
225           "SEARX_SETTINGS_PATH=${cfg.settingsFile}"
226           # searxng compatiblity https://github.com/searxng/searxng/issues/1519
227           "SEARXNG_SETTINGS_PATH=${cfg.settingsFile}"
228         ];
229         buffer-size = 32768;
230         pythonPackages = self: [ cfg.package ];
231       } // cfg.uwsgiConfig;
232     };
234   };
236   meta.maintainers = with maintainers; [ rnhmjoj ];