diff --git a/nixos/modules/services/networking/searx.nix b/nixos/modules/services/networking/searx.nix
index 60fb3d5d6d44..5b0836e67518 100644
--- a/nixos/modules/services/networking/searx.nix
+++ b/nixos/modules/services/networking/searx.nix
@@ -3,32 +3,130 @@
with lib;
let
-
+ dataDir = "/var/lib/searx";
cfg = config.services.searx;
- configFile = cfg.configFile;
+ hasEngines =
+ builtins.hasAttr "engines" cfg.settings &&
+ cfg.settings.engines != { };
+
+ # Script to merge NixOS settings with
+ # the default settings.yml bundled in searx.
+ mergeConfig = ''
+ cd ${dataDir}
+ # find the default settings.yml
+ default=$(find '${cfg.package}/' -name settings.yml)
+
+ # write NixOS settings as JSON
+ cat <<'EOF' > settings.json
+ ${builtins.toJSON cfg.settings}
+ EOF
+
+ ${optionalString hasEngines ''
+ # extract and convert the default engines array to an object
+ ${pkgs.yq-go}/bin/yq r "$default" engines -j | \
+ ${pkgs.jq}/bin/jq 'reduce .[] as $e ({}; .[$e.name] = $e)' \
+ > engines.json
+
+ # merge and update the NixOS engines with the newly created object
+ cp settings.json temp.json
+ ${pkgs.jq}/bin/jq -s '. as [$s, $e] | $s | .engines |=
+ ($e * . | to_entries | map (.value))' \
+ temp.json engines.json > settings.json
+
+ # clean up temporary files
+ rm {engines,temp}.json
+ ''}
+
+ # merge the default and NixOS settings
+ ${pkgs.yq-go}/bin/yq m -P settings.json "$default" > settings.yml
+ rm settings.json
+
+ # substitute environment variables
+ env -0 | while IFS='=' read -r -d ''' n v; do
+ sed "s#@$n@#$v#g" -i settings.yml
+ done
+ '';
in
{
+ imports = [
+ (mkRenamedOptionModule
+ [ "services" "searx" "configFile" ]
+ [ "services" "searx" "settingsFile" ])
+ ];
+
###### interface
options = {
services.searx = {
- enable = mkEnableOption
- "the searx server. See https://github.com/asciimoo/searx";
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ relatedPackages = [ "searx" ];
+ description = "Whether to enable Searx, the meta search engine.";
+ };
- configFile = mkOption {
+ environmentFile = mkOption {
type = types.nullOr types.path;
default = null;
- description = "
- The path of the Searx server configuration file. If no file
- is specified, a default file is used (default config file has
- debug mode enabled).
- ";
+ description = ''
+ Environment file (see systemd.exec(5)
+ "EnvironmentFile=" section for the syntax) to define variables for
+ Searx. This option can be used to safely include secret keys into the
+ Searx configuration.
+ '';
+ };
+
+ settings = mkOption {
+ type = types.attrs;
+ default = { };
+ example = literalExample ''
+ { server.port = 8080;
+ server.bind_address = "0.0.0.0";
+ server.secret_key = "@SEARX_SECRET_KEY@";
+
+ engines.wolframalpha =
+ { shortcut = "wa";
+ api_key = "@WOLFRAM_API_KEY@";
+ engine = "wolframalpha_api";
+ };
+ }
+ '';
+ description = ''
+ Searx settings. These will be merged with (taking precedence over)
+ the default configuration. It's also possible to refer to
+ environment variables
+ (defined in )
+ using the syntax @VARIABLE_NAME@.
+
+
+ For available settings, see the Searx
+ docs.
+
+
+ '';
+ };
+
+ settingsFile = mkOption {
+ type = types.path;
+ default = "${dataDir}/settings.yml";
+ description = ''
+ The path of the Searx server settings.yml file. If no file is
+ specified, a default file is used (default config file has debug mode
+ enabled). Note: setting this options overrides
+ .
+
+
+ This file, along with any secret key it contains, will be copied
+ into the world-readable Nix store.
+
+
+ '';
};
package = mkOption {
@@ -46,30 +144,20 @@ in
###### implementation
config = mkIf config.services.searx.enable {
-
- users.users.searx =
- { uid = config.ids.uids.searx;
- description = "Searx user";
- createHome = true;
- home = "/var/lib/searx";
- };
-
- users.groups.searx =
- { gid = config.ids.gids.searx;
- };
-
- systemd.services.searx =
- {
- description = "Searx server, the meta search engine.";
- after = [ "network.target" ];
- wantedBy = [ "multi-user.target" ];
- serviceConfig = {
- User = "searx";
- ExecStart = "${cfg.package}/bin/searx-run";
- };
- } // (optionalAttrs (configFile != null) {
- environment.SEARX_SETTINGS_PATH = configFile;
- });
+ systemd.services.searx = {
+ description = "Searx server, the meta search engine.";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ User = "searx";
+ DynamicUser = true;
+ ExecStart = "${cfg.package}/bin/searx-run";
+ StateDirectory = "searx";
+ } // optionalAttrs (cfg.environmentFile != null)
+ { EnvironmentFile = builtins.toPath cfg.environmentFile; };
+ environment.SEARX_SETTINGS_PATH = cfg.settingsFile;
+ preStart = mergeConfig;
+ };
environment.systemPackages = [ cfg.package ];