diff options
Diffstat (limited to 'nixos/modules/services/web-apps')
-rw-r--r-- | nixos/modules/services/web-apps/akkoma.nix | 2 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/alps.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/c2fmzq-server.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/code-server.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/healthchecks.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/netbox.nix | 20 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/nextcloud.nix | 211 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/openvscode-server.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/peering-manager.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/suwayomi-server.md | 108 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/suwayomi-server.nix | 260 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/wordpress.nix | 10 |
12 files changed, 496 insertions, 121 deletions
diff --git a/nixos/modules/services/web-apps/akkoma.nix b/nixos/modules/services/web-apps/akkoma.nix index 8980556ab0142..4cd9e26643787 100644 --- a/nixos/modules/services/web-apps/akkoma.nix +++ b/nixos/modules/services/web-apps/akkoma.nix @@ -974,7 +974,7 @@ in { # This service depends on network-online.target and is sequenced after # it because it requires access to the Internet to function properly. bindsTo = [ "akkoma-config.service" ]; - wants = [ "network-online.service" ]; + wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; after = [ "akkoma-config.target" diff --git a/nixos/modules/services/web-apps/alps.nix b/nixos/modules/services/web-apps/alps.nix index 05fb676102df4..81c6b8ad30b5f 100644 --- a/nixos/modules/services/web-apps/alps.nix +++ b/nixos/modules/services/web-apps/alps.nix @@ -94,6 +94,7 @@ in { description = "alps is a simple and extensible webmail."; documentation = [ "https://git.sr.ht/~migadu/alps" ]; wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; after = [ "network.target" "network-online.target" ]; serviceConfig = { diff --git a/nixos/modules/services/web-apps/c2fmzq-server.nix b/nixos/modules/services/web-apps/c2fmzq-server.nix index 87938fe160e14..dee131182de16 100644 --- a/nixos/modules/services/web-apps/c2fmzq-server.nix +++ b/nixos/modules/services/web-apps/c2fmzq-server.nix @@ -80,6 +80,7 @@ in { description = "c2FmZQ-server"; documentation = [ "https://github.com/c2FmZQ/c2FmZQ/blob/main/README.md" ]; wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; after = [ "network.target" "network-online.target" ]; serviceConfig = { diff --git a/nixos/modules/services/web-apps/code-server.nix b/nixos/modules/services/web-apps/code-server.nix index 11601f6c30449..d087deb7848d0 100644 --- a/nixos/modules/services/web-apps/code-server.nix +++ b/nixos/modules/services/web-apps/code-server.nix @@ -205,6 +205,7 @@ in { systemd.services.code-server = { description = "Code server"; wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; after = [ "network-online.target" ]; path = cfg.extraPackages; environment = { diff --git a/nixos/modules/services/web-apps/healthchecks.nix b/nixos/modules/services/web-apps/healthchecks.nix index e5e425a29d54c..1d439f162313b 100644 --- a/nixos/modules/services/web-apps/healthchecks.nix +++ b/nixos/modules/services/web-apps/healthchecks.nix @@ -176,6 +176,7 @@ in systemd.targets.healthchecks = { description = "Target for all Healthchecks services"; wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; after = [ "network.target" "network-online.target" ]; }; diff --git a/nixos/modules/services/web-apps/netbox.nix b/nixos/modules/services/web-apps/netbox.nix index 88d40b3abc529..d034f3234a2bd 100644 --- a/nixos/modules/services/web-apps/netbox.nix +++ b/nixos/modules/services/web-apps/netbox.nix @@ -75,13 +75,17 @@ in { package = lib.mkOption { type = lib.types.package; default = - if lib.versionAtLeast config.system.stateVersion "23.11" + if lib.versionAtLeast config.system.stateVersion "24.05" + then pkgs.netbox_3_7 + else if lib.versionAtLeast config.system.stateVersion "23.11" then pkgs.netbox_3_6 else if lib.versionAtLeast config.system.stateVersion "23.05" then pkgs.netbox_3_5 else pkgs.netbox_3_3; defaultText = lib.literalExpression '' - if lib.versionAtLeast config.system.stateVersion "23.11" + if lib.versionAtLeast config.system.stateVersion "24.05" + then pkgs.netbox_3_7 + else if lib.versionAtLeast config.system.stateVersion "23.11" then pkgs.netbox_3_6 else if lib.versionAtLeast config.system.stateVersion "23.05" then pkgs.netbox_3_5 @@ -267,6 +271,7 @@ in { systemd.targets.netbox = { description = "Target for all NetBox services"; wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; after = [ "network-online.target" "redis-netbox.service" ]; }; @@ -305,12 +310,13 @@ in { ${pkg}/bin/netbox trace_paths --no-input ${pkg}/bin/netbox collectstatic --no-input ${pkg}/bin/netbox remove_stale_contenttypes --no-input - # TODO: remove the condition when we remove netbox_3_3 - ${lib.optionalString - (lib.versionAtLeast cfg.package.version "3.5.0") - "${pkg}/bin/netbox reindex --lazy"} + ${pkg}/bin/netbox reindex --lazy ${pkg}/bin/netbox clearsessions - ${pkg}/bin/netbox clearcache + ${lib.optionalString + # The clearcache command was removed in 3.7.0: + # https://github.com/netbox-community/netbox/issues/14458 + (lib.versionOlder cfg.package.version "3.7.0") + "${pkg}/bin/netbox clearcache"} echo "${cfg.package.version}" > "$versionFile" ''; diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix index 38c51251aac1f..0b19265942c03 100644 --- a/nixos/modules/services/web-apps/nextcloud.nix +++ b/nixos/modules/services/web-apps/nextcloud.nix @@ -99,11 +99,101 @@ let mysqlLocal = cfg.database.createLocally && cfg.config.dbtype == "mysql"; pgsqlLocal = cfg.database.createLocally && cfg.config.dbtype == "pgsql"; + nextcloudGreaterOrEqualThan = versionAtLeast cfg.package.version; + nextcloudOlderThan = versionOlder cfg.package.version; + # https://github.com/nextcloud/documentation/pull/11179 - ocmProviderIsNotAStaticDirAnymore = versionAtLeast cfg.package.version "27.1.2" - || (versionOlder cfg.package.version "27.0.0" - && versionAtLeast cfg.package.version "26.0.8"); + ocmProviderIsNotAStaticDirAnymore = nextcloudGreaterOrEqualThan "27.1.2" + || (nextcloudOlderThan "27.0.0" && nextcloudGreaterOrEqualThan "26.0.8"); + + overrideConfig = let + c = cfg.config; + requiresReadSecretFunction = c.dbpassFile != null || c.objectstore.s3.enable; + objectstoreConfig = let s3 = c.objectstore.s3; in optionalString s3.enable '' + 'objectstore' => [ + 'class' => '\\OC\\Files\\ObjectStore\\S3', + 'arguments' => [ + 'bucket' => '${s3.bucket}', + 'autocreate' => ${boolToString s3.autocreate}, + 'key' => '${s3.key}', + 'secret' => nix_read_secret('${s3.secretFile}'), + ${optionalString (s3.hostname != null) "'hostname' => '${s3.hostname}',"} + ${optionalString (s3.port != null) "'port' => ${toString s3.port},"} + 'use_ssl' => ${boolToString s3.useSsl}, + ${optionalString (s3.region != null) "'region' => '${s3.region}',"} + 'use_path_style' => ${boolToString s3.usePathStyle}, + ${optionalString (s3.sseCKeyFile != null) "'sse_c_key' => nix_read_secret('${s3.sseCKeyFile}'),"} + ], + ] + ''; + showAppStoreSetting = cfg.appstoreEnable != null || cfg.extraApps != {}; + renderedAppStoreSetting = + let + x = cfg.appstoreEnable; + in + if x == null then "false" + else boolToString x; + mkAppStoreConfig = name: { enabled, writable, ... }: optionalString enabled '' + [ 'path' => '${webroot}/${name}', 'url' => '/${name}', 'writable' => ${boolToString writable} ], + ''; + in pkgs.writeText "nextcloud-config.php" '' + <?php + ${optionalString requiresReadSecretFunction '' + function nix_read_secret($file) { + if (!file_exists($file)) { + throw new \RuntimeException(sprintf( + "Cannot start Nextcloud, secret file %s set by NixOS doesn't seem to " + . "exist! Please make sure that the file exists and has appropriate " + . "permissions for user & group 'nextcloud'!", + $file + )); + } + return trim(file_get_contents($file)); + }''} + function nix_decode_json_file($file, $error) { + if (!file_exists($file)) { + throw new \RuntimeException(sprintf($error, $file)); + } + $decoded = json_decode(file_get_contents($file), true); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw new \RuntimeException(sprintf("Cannot decode %s, because: %s", $file, json_last_error_msg())); + } + return $decoded; + } + $CONFIG = [ + 'apps_paths' => [ + ${concatStrings (mapAttrsToList mkAppStoreConfig appStores)} + ], + ${optionalString (showAppStoreSetting) "'appstoreenabled' => ${renderedAppStoreSetting},"} + ${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"} + ${optionalString (c.dbname != null) "'dbname' => '${c.dbname}',"} + ${optionalString (c.dbhost != null) "'dbhost' => '${c.dbhost}',"} + ${optionalString (c.dbuser != null) "'dbuser' => '${c.dbuser}',"} + ${optionalString (c.dbtableprefix != null) "'dbtableprefix' => '${toString c.dbtableprefix}',"} + ${optionalString (c.dbpassFile != null) '' + 'dbpassword' => nix_read_secret( + "${c.dbpassFile}" + ), + '' + } + 'dbtype' => '${c.dbtype}', + ${objectstoreConfig} + ]; + + $CONFIG = array_replace_recursive($CONFIG, nix_decode_json_file( + "${jsonFormat.generate "nextcloud-extraOptions.json" cfg.extraOptions}", + "impossible: this should never happen (decoding generated extraOptions file %s failed)" + )); + + ${optionalString (cfg.secretFile != null) '' + $CONFIG = array_replace_recursive($CONFIG, nix_decode_json_file( + "${cfg.secretFile}", + "Cannot start Nextcloud, secrets file %s set by NixOS doesn't exist!" + )); + ''} + ''; in { imports = [ @@ -787,107 +877,23 @@ in { timerConfig.Unit = "nextcloud-cron.service"; }; - systemd.tmpfiles.rules = ["d ${cfg.home} 0750 nextcloud nextcloud"]; + systemd.tmpfiles.rules = map (dir: "d ${dir} 0750 nextcloud nextcloud - -") [ + "${cfg.home}" + "${datadir}/config" + "${datadir}/data" + "${cfg.home}/store-apps" + ] ++ [ + "L+ ${datadir}/config/override.config.php - - - - ${overrideConfig}" + ]; systemd.services = { # When upgrading the Nextcloud package, Nextcloud can report errors such as # "The files of the app [all apps in /var/lib/nextcloud/apps] were not replaced correctly" # Restarting phpfpm on Nextcloud package update fixes these issues (but this is a workaround). - phpfpm-nextcloud.restartTriggers = [ webroot ]; + phpfpm-nextcloud.restartTriggers = [ webroot overrideConfig ]; nextcloud-setup = let c = cfg.config; - requiresReadSecretFunction = c.dbpassFile != null || c.objectstore.s3.enable; - objectstoreConfig = let s3 = c.objectstore.s3; in optionalString s3.enable '' - 'objectstore' => [ - 'class' => '\\OC\\Files\\ObjectStore\\S3', - 'arguments' => [ - 'bucket' => '${s3.bucket}', - 'autocreate' => ${boolToString s3.autocreate}, - 'key' => '${s3.key}', - 'secret' => nix_read_secret('${s3.secretFile}'), - ${optionalString (s3.hostname != null) "'hostname' => '${s3.hostname}',"} - ${optionalString (s3.port != null) "'port' => ${toString s3.port},"} - 'use_ssl' => ${boolToString s3.useSsl}, - ${optionalString (s3.region != null) "'region' => '${s3.region}',"} - 'use_path_style' => ${boolToString s3.usePathStyle}, - ${optionalString (s3.sseCKeyFile != null) "'sse_c_key' => nix_read_secret('${s3.sseCKeyFile}'),"} - ], - ] - ''; - - showAppStoreSetting = cfg.appstoreEnable != null || cfg.extraApps != {}; - renderedAppStoreSetting = - let - x = cfg.appstoreEnable; - in - if x == null then "false" - else boolToString x; - - nextcloudGreaterOrEqualThan = req: versionAtLeast cfg.package.version req; - - mkAppStoreConfig = name: { enabled, writable, ... }: optionalString enabled '' - [ 'path' => '${webroot}/${name}', 'url' => '/${name}', 'writable' => ${boolToString writable} ], - ''; - - overrideConfig = pkgs.writeText "nextcloud-config.php" '' - <?php - ${optionalString requiresReadSecretFunction '' - function nix_read_secret($file) { - if (!file_exists($file)) { - throw new \RuntimeException(sprintf( - "Cannot start Nextcloud, secret file %s set by NixOS doesn't seem to " - . "exist! Please make sure that the file exists and has appropriate " - . "permissions for user & group 'nextcloud'!", - $file - )); - } - return trim(file_get_contents($file)); - }''} - function nix_decode_json_file($file, $error) { - if (!file_exists($file)) { - throw new \RuntimeException(sprintf($error, $file)); - } - $decoded = json_decode(file_get_contents($file), true); - - if (json_last_error() !== JSON_ERROR_NONE) { - throw new \RuntimeException(sprintf("Cannot decode %s, because: %s", $file, json_last_error_msg())); - } - - return $decoded; - } - $CONFIG = [ - 'apps_paths' => [ - ${concatStrings (mapAttrsToList mkAppStoreConfig appStores)} - ], - ${optionalString (showAppStoreSetting) "'appstoreenabled' => ${renderedAppStoreSetting},"} - ${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"} - ${optionalString (c.dbname != null) "'dbname' => '${c.dbname}',"} - ${optionalString (c.dbhost != null) "'dbhost' => '${c.dbhost}',"} - ${optionalString (c.dbuser != null) "'dbuser' => '${c.dbuser}',"} - ${optionalString (c.dbtableprefix != null) "'dbtableprefix' => '${toString c.dbtableprefix}',"} - ${optionalString (c.dbpassFile != null) '' - 'dbpassword' => nix_read_secret( - "${c.dbpassFile}" - ), - '' - } - 'dbtype' => '${c.dbtype}', - ${objectstoreConfig} - ]; - - $CONFIG = array_replace_recursive($CONFIG, nix_decode_json_file( - "${jsonFormat.generate "nextcloud-extraOptions.json" cfg.extraOptions}", - "impossible: this should never happen (decoding generated extraOptions file %s failed)" - )); - - ${optionalString (cfg.secretFile != null) '' - $CONFIG = array_replace_recursive($CONFIG, nix_decode_json_file( - "${cfg.secretFile}", - "Cannot start Nextcloud, secrets file %s set by NixOS doesn't exist!" - )); - ''} - ''; occInstallCmd = let mkExport = { arg, value }: "export ${arg}=${value}"; dbpass = { @@ -932,6 +938,7 @@ in { after = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service"; requires = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service"; path = [ occ ]; + restartTriggers = [ overrideConfig ]; script = '' ${optionalString (c.dbpassFile != null) '' if [ ! -r "${c.dbpassFile}" ]; then @@ -959,18 +966,6 @@ in { fi '') [ "nix-apps" "apps" ]} - # create nextcloud directories. - # if the directories exist already with wrong permissions, we fix that - for dir in ${datadir}/config ${datadir}/data ${cfg.home}/store-apps; do - if [ ! -e $dir ]; then - install -o nextcloud -g nextcloud -d $dir - elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then - chgrp -R nextcloud $dir - fi - done - - ln -sf ${overrideConfig} ${datadir}/config/override.config.php - # Do not install if already installed if [[ ! -e ${datadir}/config/config.php ]]; then ${occInstallCmd} diff --git a/nixos/modules/services/web-apps/openvscode-server.nix b/nixos/modules/services/web-apps/openvscode-server.nix index 76a19dccae165..81b9d1f3b4c8c 100644 --- a/nixos/modules/services/web-apps/openvscode-server.nix +++ b/nixos/modules/services/web-apps/openvscode-server.nix @@ -159,6 +159,7 @@ in systemd.services.openvscode-server = { description = "OpenVSCode server"; wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; after = [ "network-online.target" ]; path = cfg.extraPackages; environment = cfg.extraEnvironment; diff --git a/nixos/modules/services/web-apps/peering-manager.nix b/nixos/modules/services/web-apps/peering-manager.nix index d6f6077268d46..0382ce7174738 100644 --- a/nixos/modules/services/web-apps/peering-manager.nix +++ b/nixos/modules/services/web-apps/peering-manager.nix @@ -196,6 +196,7 @@ in { systemd.targets.peering-manager = { description = "Target for all Peering Manager services"; wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; after = [ "network-online.target" "redis-peering-manager.service" ]; }; diff --git a/nixos/modules/services/web-apps/suwayomi-server.md b/nixos/modules/services/web-apps/suwayomi-server.md new file mode 100644 index 0000000000000..ff1e06c8a53ae --- /dev/null +++ b/nixos/modules/services/web-apps/suwayomi-server.md @@ -0,0 +1,108 @@ +# Suwayomi-Server {#module-services-suwayomi-server} + +A free and open source manga reader server that runs extensions built for Tachiyomi. + +## Basic usage {#module-services-suwayomi-server-basic-usage} + +By default, the module will execute Suwayomi-Server backend and web UI: + +```nix +{ ... }: + +{ + services.suwayomi-server = { + enable = true; + }; +} +``` + +It runs in the systemd service named `suwayomi-server` in the data directory `/var/lib/suwayomi-server`. + +You can change the default parameters with some other parameters: +```nix +{ ... }: + +{ + services.suwayomi-server = { + enable = true; + + dataDir = "/var/lib/suwayomi"; # Default is "/var/lib/suwayomi-server" + openFirewall = true; + + settings = { + server.port = 4567; + }; + }; +} +``` + +If you want to create a desktop icon, you can activate the system tray option: + +```nix +{ ... }: + +{ + services.suwayomi-server = { + enable = true; + + dataDir = "/var/lib/suwayomi"; # Default is "/var/lib/suwayomi-server" + openFirewall = true; + + settings = { + server.port = 4567; + server.enableSystemTray = true; + }; + }; +} +``` + +## Basic authentication {#module-services-suwayomi-server-basic-auth} + +You can configure a basic authentication to the web interface with: + +```nix +{ ... }: + +{ + services.suwayomi-server = { + enable = true; + + openFirewall = true; + + settings = { + server.port = 4567; + server = { + basicAuthEnabled = true; + basicAuthUsername = "username"; + + # NOTE: this is not a real upstream option + basicAuthPasswordFile = ./path/to/the/password/file; + }; + }; + }; +} +``` + +## Extra configuration {#module-services-suwayomi-server-extra-config} + +Not all the configuration options are available directly in this module, but you can add the other options of suwayomi-server with: + +```nix +{ ... }: + +{ + services.suwayomi-server = { + enable = true; + + openFirewall = true; + + settings = { + server = { + port = 4567; + autoDownloadNewChapters = false; + maxSourcesInParallel" = 6; + }; + }; + }; +} +``` diff --git a/nixos/modules/services/web-apps/suwayomi-server.nix b/nixos/modules/services/web-apps/suwayomi-server.nix new file mode 100644 index 0000000000000..c4c1540edbee5 --- /dev/null +++ b/nixos/modules/services/web-apps/suwayomi-server.nix @@ -0,0 +1,260 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.services.suwayomi-server; + inherit (lib) mkOption mdDoc mkEnableOption mkIf types; +in +{ + options = { + services.suwayomi-server = { + enable = mkEnableOption (mdDoc "Suwayomi, a free and open source manga reader server that runs extensions built for Tachiyomi."); + + package = lib.mkPackageOptionMD pkgs "suwayomi-server" { }; + + dataDir = mkOption { + type = types.path; + default = "/var/lib/suwayomi-server"; + example = "/var/data/mangas"; + description = mdDoc '' + The path to the data directory in which Suwayomi-Server will download scans. + ''; + }; + + user = mkOption { + type = types.str; + default = "suwayomi"; + example = "root"; + description = mdDoc '' + User account under which Suwayomi-Server runs. + ''; + }; + + group = mkOption { + type = types.str; + default = "suwayomi"; + example = "medias"; + description = mdDoc '' + Group under which Suwayomi-Server runs. + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = mdDoc '' + Whether to open the firewall for the port in {option}`services.suwayomi-server.settings.server.port`. + ''; + }; + + settings = mkOption { + type = types.submodule { + freeformType = + let + recursiveAttrsType = with types; attrsOf (nullOr (oneOf [ + str + path + int + float + bool + (listOf str) + (recursiveAttrsType // { description = "instances of this type recursively"; }) + ])); + in + recursiveAttrsType; + options = { + server = { + ip = mkOption { + type = types.str; + default = "0.0.0.0"; + example = "127.0.0.1"; + description = mdDoc '' + The ip that Suwayomi will bind to. + ''; + }; + + port = mkOption { + type = types.port; + default = 8080; + example = 4567; + description = mdDoc '' + The port that Suwayomi will listen to. + ''; + }; + + basicAuthEnabled = mkEnableOption (mdDoc '' + Add basic access authentication to Suwayomi-Server. + Enabling this option is useful when hosting on a public network/the Internet + ''); + + basicAuthUsername = mkOption { + type = types.nullOr types.str; + default = null; + description = mdDoc '' + The username value that you have to provide when authenticating. + ''; + }; + + # NOTE: this is not a real upstream option + basicAuthPasswordFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/var/secrets/suwayomi-server-password"; + description = mdDoc '' + The password file containing the value that you have to provide when authenticating. + ''; + }; + + downloadAsCbz = mkOption { + type = types.bool; + default = false; + description = mdDoc '' + Download chapters as `.cbz` files. + ''; + }; + + localSourcePath = mkOption { + type = types.path; + default = cfg.dataDir; + defaultText = lib.literalExpression "suwayomi-server.dataDir"; + example = "/var/data/local_mangas"; + description = mdDoc '' + Path to the local source folder. + ''; + }; + + systemTrayEnabled = mkOption { + type = types.bool; + default = false; + description = mdDoc '' + Whether to enable a system tray icon, if possible. + ''; + }; + }; + }; + }; + description = mdDoc '' + Configuration to write to {file}`server.conf`. + See <https://github.com/Suwayomi/Suwayomi-Server/wiki/Configuring-Suwayomi-Server> for more information. + ''; + default = { }; + example = { + server.socksProxyEnabled = true; + server.socksProxyHost = "yourproxyhost.com"; + server.socksProxyPort = "8080"; + }; + }; + }; + }; + + config = mkIf cfg.enable { + + assertions = [{ + assertion = with cfg.settings.server; basicAuthEnabled -> (basicAuthUsername != null && basicAuthPasswordFile != null); + message = '' + [suwayomi-server]: the username and the password file cannot be null when the basic auth is enabled + ''; + }]; + + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.server.port ]; + + users.groups = mkIf (cfg.group == "suwayomi") { + suwayomi = { }; + }; + + users.users = mkIf (cfg.user == "suwayomi") { + suwayomi = { + group = cfg.group; + # Need to set the user home because the package writes to ~/.local/Tachidesk + home = cfg.dataDir; + description = "Suwayomi Daemon user"; + isSystemUser = true; + }; + }; + + systemd.tmpfiles.settings."10-suwayomi-server" = { + "${cfg.dataDir}/.local/share/Tachidesk".d = { + mode = "0700"; + inherit (cfg) user group; + }; + }; + + systemd.services.suwayomi-server = + let + flattenConfig = prefix: config: + lib.foldl' + lib.mergeAttrs + { } + (lib.attrValues + (lib.mapAttrs + (k: v: + if !(lib.isAttrs v) + then { "${prefix}${k}" = v; } + else flattenConfig "${prefix}${k}." v + ) + config + ) + ); + + # HOCON is a JSON superset that suwayomi-server use for configuration + toHOCON = attr: + let + attrType = builtins.typeOf attr; + in + if builtins.elem attrType [ "string" "path" "int" "float" ] + then ''"${toString attr}"'' + else if attrType == "bool" + then lib.boolToString attr + else if attrType == "list" + then "[\n${lib.concatMapStringsSep ",\n" toHOCON attr}\n]" + else # attrs, lambda, null + throw '' + [suwayomi-server]: invalid config value type '${attrType}'. + ''; + + configFile = pkgs.writeText "server.conf" (lib.pipe cfg.settings [ + (settings: lib.recursiveUpdate settings { + server.basicAuthPasswordFile = null; + server.basicAuthPassword = + if settings.server.basicAuthEnabled + then "$TACHIDESK_SERVER_BASIC_AUTH_PASSWORD" + else null; + }) + (flattenConfig "") + (lib.filterAttrs (_: x: x != null)) + (lib.mapAttrsToList (name: value: ''${name} = ${toHOCON value}'')) + lib.concatLines + ]); + + in + { + description = "A free and open source manga reader server that runs extensions built for Tachiyomi."; + + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + + script = '' + ${lib.optionalString cfg.settings.server.basicAuthEnabled '' + export TACHIDESK_SERVER_BASIC_AUTH_PASSWORD="$(<${cfg.settings.server.basicAuthPasswordFile})" + ''} + ${lib.getExe pkgs.envsubst} -i ${configFile} -o ${cfg.dataDir}/.local/share/Tachidesk/server.conf + ${lib.getExe cfg.package} -Dsuwayomi.tachidesk.config.server.rootDir=${cfg.dataDir} + ''; + + serviceConfig = { + User = cfg.user; + Group = cfg.group; + + Type = "simple"; + Restart = "on-failure"; + + StateDirectory = mkIf (cfg.dataDir == "/var/lib/suwayomi-server") "suwayomi-server"; + }; + }; + }; + + meta = { + maintainers = with lib.maintainers; [ ratcornu ]; + doc = ./suwayomi-server.md; + }; +} diff --git a/nixos/modules/services/web-apps/wordpress.nix b/nixos/modules/services/web-apps/wordpress.nix index 002d6683b2ed5..2f7306309d694 100644 --- a/nixos/modules/services/web-apps/wordpress.nix +++ b/nixos/modules/services/web-apps/wordpress.nix @@ -174,22 +174,22 @@ let List of path(s) to respective language(s) which are copied from the 'languages' directory. ''; example = literalExpression '' - [( + [ # Let's package the German language. # For other languages try to replace language and country code in the download URL with your desired one. # Reference https://translate.wordpress.org for available translations and # codes. - language-de = pkgs.stdenv.mkDerivation { + (pkgs.stdenv.mkDerivation { name = "language-de"; src = pkgs.fetchurl { url = "https://de.wordpress.org/wordpress-''${pkgs.wordpress.version}-de_DE.tar.gz"; # Name is required to invalidate the hash when wordpress is updated - name = "wordpress-''${pkgs.wordpress.version}-language-de" + name = "wordpress-''${pkgs.wordpress.version}-language-de"; sha256 = "sha256-dlas0rXTSV4JAl8f/UyMbig57yURRYRhTMtJwF9g8h0="; }; installPhase = "mkdir -p $out; cp -r ./wp-content/languages/* $out/"; - }; - )]; + }) + ]; ''; }; |