at 23.11-pre 6.8 kB view raw
1{ options, config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 runDir = "/run/searx"; 7 8 cfg = config.services.searx; 9 10 settingsFile = pkgs.writeText "settings.yml" 11 (builtins.toJSON cfg.settings); 12 13 generateConfig = '' 14 cd ${runDir} 15 16 # write NixOS settings as JSON 17 ( 18 umask 077 19 cp --no-preserve=mode ${settingsFile} settings.yml 20 ) 21 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 ''; 27 28 settingType = with types; (oneOf 29 [ bool int float str 30 (listOf settingType) 31 (attrsOf settingType) 32 ]) // { description = "JSON value"; }; 33 34in 35 36{ 37 38 imports = [ 39 (mkRenamedOptionModule 40 [ "services" "searx" "configFile" ] 41 [ "services" "searx" "settingsFile" ]) 42 ]; 43 44 ###### interface 45 46 options = { 47 48 services.searx = { 49 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 }; 56 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 }; 67 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@"; 75 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@`. 90 91 ::: {.note} 92 For available settings, see the Searx 93 [docs](https://searx.github.io/searx/admin/settings.html). 94 ::: 95 ''; 96 }; 97 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). 106 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 }; 113 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 }; 120 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 unnecessary for LAN or local-only use. 128 129 ::: {.warning} 130 The built-in HTTP server logs all queries by default. 131 ::: 132 ''; 133 }; 134 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 }; 152 153 }; 154 155 }; 156 157 158 ###### implementation 159 160 config = mkIf cfg.enable { 161 environment.systemPackages = [ cfg.package ]; 162 163 users.users.searx = 164 { description = "Searx daemon user"; 165 group = "searx"; 166 isSystemUser = true; 167 }; 168 169 users.groups.searx = { }; 170 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 }; 183 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 }; 200 201 systemd.services.uwsgi = mkIf (cfg.runInUwsgi) 202 { requires = [ "searx-init.service" ]; 203 after = [ "searx-init.service" ]; 204 }; 205 206 services.searx.settings = { 207 # merge NixOS settings with defaults settings.yml 208 use_default_settings = mkDefault true; 209 }; 210 211 services.uwsgi = mkIf (cfg.runInUwsgi) { 212 enable = true; 213 plugins = [ "python3" ]; 214 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 compatibility 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 }; 233 234 }; 235 236 meta.maintainers = with maintainers; [ rnhmjoj ]; 237}