at 25.11-pre 9.3 kB view raw
1{ 2 options, 3 config, 4 lib, 5 pkgs, 6 ... 7}: 8 9with lib; 10 11let 12 runDir = "/run/searx"; 13 14 cfg = config.services.searx; 15 16 settingsFile = pkgs.writeText "settings.yml" (builtins.toJSON cfg.settings); 17 18 limiterSettingsFile = (pkgs.formats.toml { }).generate "limiter.toml" cfg.limiterSettings; 19 faviconsSettingsFile = (pkgs.formats.toml { }).generate "favicons.toml" cfg.faviconsSettings; 20 21 generateConfig = '' 22 cd ${runDir} 23 24 # write NixOS settings as JSON 25 ( 26 umask 077 27 cp --no-preserve=mode ${settingsFile} settings.yml 28 ) 29 30 # substitute environment variables 31 env -0 | while IFS='=' read -r -d ''' n v; do 32 sed "s#@$n@#$v#g" -i settings.yml 33 done 34 ''; 35 36 settingType = 37 with types; 38 (oneOf [ 39 bool 40 int 41 float 42 str 43 (listOf settingType) 44 (attrsOf settingType) 45 ]) 46 // { 47 description = "JSON value"; 48 }; 49 50in 51 52{ 53 54 imports = [ 55 (mkRenamedOptionModule [ "services" "searx" "configFile" ] [ "services" "searx" "settingsFile" ]) 56 ]; 57 58 options = { 59 services.searx = { 60 enable = mkOption { 61 type = types.bool; 62 default = false; 63 relatedPackages = [ "searx" ]; 64 description = "Whether to enable Searx, the meta search engine."; 65 }; 66 67 environmentFile = mkOption { 68 type = types.nullOr types.path; 69 default = null; 70 description = '' 71 Environment file (see {manpage}`systemd.exec(5)` 72 "EnvironmentFile=" section for the syntax) to define variables for 73 Searx. This option can be used to safely include secret keys into the 74 Searx configuration. 75 ''; 76 }; 77 78 redisCreateLocally = mkOption { 79 type = types.bool; 80 default = false; 81 description = '' 82 Configure a local Redis server for SearXNG. This is required if you 83 want to enable the rate limiter and bot protection of SearXNG. 84 ''; 85 }; 86 87 settings = mkOption { 88 type = types.attrsOf settingType; 89 default = { }; 90 example = literalExpression '' 91 { server.port = 8080; 92 server.bind_address = "0.0.0.0"; 93 server.secret_key = "@SEARX_SECRET_KEY@"; 94 95 engines = lib.singleton 96 { name = "wolframalpha"; 97 shortcut = "wa"; 98 api_key = "@WOLFRAM_API_KEY@"; 99 engine = "wolframalpha_api"; 100 }; 101 } 102 ''; 103 description = '' 104 Searx settings. These will be merged with (taking precedence over) 105 the default configuration. It's also possible to refer to 106 environment variables 107 (defined in [](#opt-services.searx.environmentFile)) 108 using the syntax `@VARIABLE_NAME@`. 109 110 ::: {.note} 111 For available settings, see the Searx 112 [docs](https://searx.github.io/searx/admin/settings.html). 113 ::: 114 ''; 115 }; 116 117 settingsFile = mkOption { 118 type = types.path; 119 default = "${runDir}/settings.yml"; 120 description = '' 121 The path of the Searx server settings.yml file. If no file is 122 specified, a default file is used (default config file has debug mode 123 enabled). Note: setting this options overrides 124 [](#opt-services.searx.settings). 125 126 ::: {.warning} 127 This file, along with any secret key it contains, will be copied 128 into the world-readable Nix store. 129 ::: 130 ''; 131 }; 132 133 limiterSettings = mkOption { 134 type = types.attrsOf settingType; 135 default = { }; 136 example = literalExpression '' 137 { 138 real_ip = { 139 x_for = 1; 140 ipv4_prefix = 32; 141 ipv6_prefix = 56; 142 } 143 botdetection.ip_lists.block_ip = [ 144 # "93.184.216.34" # example.org 145 ]; 146 } 147 ''; 148 description = '' 149 Limiter settings for SearXNG. 150 151 ::: {.note} 152 For available settings, see the SearXNG 153 [schema file](https://github.com/searxng/searxng/blob/master/searx/limiter.toml). 154 ::: 155 ''; 156 }; 157 158 faviconsSettings = mkOption { 159 type = types.attrsOf settingType; 160 default = { }; 161 example = literalExpression '' 162 { 163 favicons = { 164 cfg_schema = 1; 165 cache = { 166 db_url = "/run/searx/faviconcache.db"; 167 HOLD_TIME = 5184000; 168 LIMIT_TOTAL_BYTES = 2147483648; 169 BLOB_MAX_BYTES = 40960; 170 MAINTENANCE_MODE = "auto"; 171 MAINTENANCE_PERIOD = 600; 172 }; 173 }; 174 } 175 ''; 176 description = '' 177 Favicons settings for SearXNG. 178 179 ::: {.note} 180 For available settings, see the SearXNG 181 [schema file](https://github.com/searxng/searxng/blob/master/searx/favicons/favicons.toml). 182 ::: 183 ''; 184 }; 185 186 package = mkPackageOption pkgs "searxng" { }; 187 188 runInUwsgi = mkOption { 189 type = types.bool; 190 default = false; 191 description = '' 192 Whether to run searx in uWSGI as a "vassal", instead of using its 193 built-in HTTP server. This is the recommended mode for public or 194 large instances, but is unnecessary for LAN or local-only use. 195 196 ::: {.warning} 197 The built-in HTTP server logs all queries by default. 198 ::: 199 ''; 200 }; 201 202 uwsgiConfig = mkOption { 203 type = options.services.uwsgi.instance.type; 204 default = { 205 http = ":8080"; 206 }; 207 example = literalExpression '' 208 { 209 disable-logging = true; 210 http = ":8080"; # serve via HTTP... 211 socket = "/run/searx/searx.sock"; # ...or UNIX socket 212 chmod-socket = "660"; # allow the searx group to read/write to the socket 213 } 214 ''; 215 description = '' 216 Additional configuration of the uWSGI vassal running searx. It 217 should notably specify on which interfaces and ports the vassal 218 should listen. 219 ''; 220 }; 221 222 }; 223 224 }; 225 226 config = mkIf cfg.enable { 227 environment.systemPackages = [ cfg.package ]; 228 229 users.users.searx = { 230 description = "Searx daemon user"; 231 group = "searx"; 232 isSystemUser = true; 233 }; 234 235 users.groups.searx = { }; 236 237 systemd.services.searx-init = { 238 description = "Initialise Searx settings"; 239 serviceConfig = 240 { 241 Type = "oneshot"; 242 RemainAfterExit = true; 243 User = "searx"; 244 RuntimeDirectory = "searx"; 245 RuntimeDirectoryMode = "750"; 246 } 247 // optionalAttrs (cfg.environmentFile != null) { 248 EnvironmentFile = builtins.toPath cfg.environmentFile; 249 }; 250 script = generateConfig; 251 }; 252 253 systemd.services.searx = mkIf (!cfg.runInUwsgi) { 254 description = "Searx server, the meta search engine."; 255 wantedBy = [ 256 "network.target" 257 "multi-user.target" 258 ]; 259 requires = [ "searx-init.service" ]; 260 after = [ "searx-init.service" ]; 261 serviceConfig = 262 { 263 User = "searx"; 264 Group = "searx"; 265 ExecStart = lib.getExe cfg.package; 266 } 267 // optionalAttrs (cfg.environmentFile != null) { 268 EnvironmentFile = builtins.toPath cfg.environmentFile; 269 }; 270 environment = { 271 SEARX_SETTINGS_PATH = cfg.settingsFile; 272 SEARXNG_SETTINGS_PATH = cfg.settingsFile; 273 }; 274 }; 275 276 systemd.services.uwsgi = mkIf cfg.runInUwsgi { 277 requires = [ "searx-init.service" ]; 278 after = [ "searx-init.service" ]; 279 }; 280 281 services.searx.settings = { 282 # merge NixOS settings with defaults settings.yml 283 use_default_settings = mkDefault true; 284 redis.url = lib.mkIf cfg.redisCreateLocally "unix://${config.services.redis.servers.searx.unixSocket}"; 285 }; 286 287 services.uwsgi = mkIf cfg.runInUwsgi { 288 enable = true; 289 plugins = [ "python3" ]; 290 291 instance.type = "emperor"; 292 instance.vassals.searx = { 293 type = "normal"; 294 strict = true; 295 immediate-uid = "searx"; 296 immediate-gid = "searx"; 297 lazy-apps = true; 298 enable-threads = true; 299 module = "searx.webapp"; 300 env = [ 301 # TODO: drop this as it is only required for searx 302 "SEARX_SETTINGS_PATH=${cfg.settingsFile}" 303 # searxng compatibility https://github.com/searxng/searxng/issues/1519 304 "SEARXNG_SETTINGS_PATH=${cfg.settingsFile}" 305 ]; 306 buffer-size = 32768; 307 pythonPackages = self: [ cfg.package ]; 308 } // cfg.uwsgiConfig; 309 }; 310 311 services.redis.servers.searx = lib.mkIf cfg.redisCreateLocally { 312 enable = true; 313 user = "searx"; 314 port = 0; 315 }; 316 317 environment.etc = { 318 "searxng/limiter.toml" = lib.mkIf (cfg.limiterSettings != { }) { 319 source = limiterSettingsFile; 320 }; 321 "searxng/favicons.toml" = lib.mkIf (cfg.faviconsSettings != { }) { 322 source = faviconsSettingsFile; 323 }; 324 }; 325 }; 326 327 meta.maintainers = with maintainers; [ 328 rnhmjoj 329 _999eagle 330 ]; 331}