diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/web-apps')
14 files changed, 854 insertions, 154 deletions
diff --git a/nixpkgs/nixos/modules/services/web-apps/codimd.nix b/nixpkgs/nixos/modules/services/web-apps/codimd.nix index 751f81649dd..ab922a38e5c 100644 --- a/nixpkgs/nixos/modules/services/web-apps/codimd.nix +++ b/nixpkgs/nixos/modules/services/web-apps/codimd.nix @@ -93,7 +93,7 @@ in type = types.bool; default = true; description = '' - Wheter to enable HSTS if HTTPS is also enabled. + Whether to enable HSTS if HTTPS is also enabled. ''; }; maxAgeSeconds = mkOption { @@ -385,7 +385,7 @@ in type = types.bool; default = true; description = '' - Wether to enable email registration. + Whether to enable email registration. ''; }; allowGravatar = mkOption { diff --git a/nixpkgs/nixos/modules/services/web-apps/convos.nix b/nixpkgs/nixos/modules/services/web-apps/convos.nix new file mode 100644 index 00000000000..8be11eec9f3 --- /dev/null +++ b/nixpkgs/nixos/modules/services/web-apps/convos.nix @@ -0,0 +1,72 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.convos; +in +{ + options.services.convos = { + enable = mkEnableOption "Convos"; + listenPort = mkOption { + type = types.port; + default = 3000; + example = 8080; + description = "Port the web interface should listen on"; + }; + listenAddress = mkOption { + type = types.str; + default = "*"; + example = "127.0.0.1"; + description = "Address or host the web interface should listen on"; + }; + reverseProxy = mkOption { + type = types.bool; + default = false; + description = '' + Enables reverse proxy support. This will allow Convos to automatically + pick up the <literal>X-Forwarded-For</literal> and + <literal>X-Request-Base</literal> HTTP headers set in your reverse proxy + web server. Note that enabling this option without a reverse proxy in + front will be a security issue. + ''; + }; + }; + config = mkIf cfg.enable { + systemd.services.convos = { + description = "Convos Service"; + wantedBy = [ "multi-user.target" ]; + after = [ "networking.target" ]; + environment = { + CONVOS_HOME = "%S/convos"; + CONVOS_REVERSE_PROXY = if cfg.reverseProxy then "1" else "0"; + MOJO_LISTEN = "http://${toString cfg.listenAddress}:${toString cfg.listenPort}"; + }; + serviceConfig = { + ExecStart = "${pkgs.convos}/bin/convos daemon"; + Restart = "on-failure"; + StateDirectory = "convos"; + WorkingDirectory = "%S/convos"; + DynamicUser = true; + MemoryDenyWriteExecute = true; + ProtectHome = true; + ProtectClock = true; + ProtectHostname = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateUsers = true; + LockPersonality = true; + RestrictRealtime = true; + RestrictNamespaces = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6"]; + SystemCallFilter = "@system-service"; + SystemCallArchitectures = "native"; + CapabilityBoundingSet = ""; + }; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/web-apps/dokuwiki.nix b/nixpkgs/nixos/modules/services/web-apps/dokuwiki.nix index 33a828fa2cb..d9ebb3a9880 100644 --- a/nixpkgs/nixos/modules/services/web-apps/dokuwiki.nix +++ b/nixpkgs/nixos/modules/services/web-apps/dokuwiki.nix @@ -2,7 +2,7 @@ let - inherit (lib) mkEnableOption mkForce mkIf mkMerge mkOption optionalAttrs recursiveUpdate types; + inherit (lib) mkEnableOption mkForce mkIf mkMerge mkOption optionalAttrs recursiveUpdate types maintainers; inherit (lib) concatMapStringsSep flatten mapAttrs mapAttrs' mapAttrsToList nameValuePair concatMapStringSep; eachSite = config.services.dokuwiki; @@ -95,7 +95,7 @@ let aclFile = mkOption { type = with types; nullOr str; - default = if (config.aclUse && config.acl == null) then "/var/lib/dokuwiki/${name}/users.auth.php" else null; + default = if (config.aclUse && config.acl == null) then "/var/lib/dokuwiki/${name}/acl.auth.php" else null; description = '' Location of the dokuwiki acl rules. Mutually exclusive with services.dokuwiki.acl Mutually exclusive with services.dokuwiki.acl which is preferred. @@ -249,22 +249,19 @@ let nginx = mkOption { type = types.submodule ( recursiveUpdate - (import ../web-servers/nginx/vhost-options.nix { inherit config lib; }) - { - # Enable encryption by default, - options.forceSSL.default = true; - options.enableACME.default = true; - } + (import ../web-servers/nginx/vhost-options.nix { inherit config lib; }) {} ); - default = {forceSSL = true; enableACME = true;}; + default = {}; example = { serverAliases = [ "wiki.\${config.networking.domain}" ]; - enableACME = false; + # To enable encryption and let let's encrypt take care of certificate + forceSSL = true; + enableACME = true; }; description = '' - With this option, you can customize the nginx virtualHost which already has sensible defaults for DokuWiki. + With this option, you can customize the nginx virtualHost settings. ''; }; }; @@ -276,7 +273,7 @@ in services.dokuwiki = mkOption { type = types.attrsOf (types.submodule siteOpts); default = {}; - description = "Sepcification of one or more dokuwiki sites to service."; + description = "Sepcification of one or more dokuwiki sites to serve."; }; }; @@ -321,7 +318,7 @@ in enable = true; virtualHosts = mapAttrs (hostName: cfg: mkMerge [ cfg.nginx { root = mkForce "${pkg hostName cfg}/share/dokuwiki"; - extraConfig = "fastcgi_param HTTPS on;"; + extraConfig = lib.optionalString (cfg.nginx.addSSL || cfg.nginx.forceSSL || cfg.nginx.onlySSL || cfg.nginx.enableACME) "fastcgi_param HTTPS on;"; locations."~ /(conf/|bin/|inc/|install.php)" = { extraConfig = "deny all;"; @@ -359,7 +356,7 @@ in fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param REDIRECT_STATUS 200; fastcgi_pass unix:${config.services.phpfpm.pools."dokuwiki-${hostName}".socket}; - fastcgi_param HTTPS on; + ${lib.optionalString (cfg.nginx.addSSL || cfg.nginx.forceSSL || cfg.nginx.onlySSL || cfg.nginx.enableACME) "fastcgi_param HTTPS on;"} ''; }; }]) eachSite; @@ -385,4 +382,7 @@ in isSystemUser = true; }; }; + + meta.maintainers = with maintainers; [ _1000101 ]; + } diff --git a/nixpkgs/nixos/modules/services/web-apps/gerrit.nix b/nixpkgs/nixos/modules/services/web-apps/gerrit.nix index b184c0754d4..657b1a4fc5b 100644 --- a/nixpkgs/nixos/modules/services/web-apps/gerrit.nix +++ b/nixpkgs/nixos/modules/services/web-apps/gerrit.nix @@ -17,6 +17,10 @@ let lib.generators.toGitINI cfg.settings ); + replicationConfig = pkgs.writeText "replication.conf" ( + lib.generators.toGitINI cfg.replicationSettings + ); + # Wrap the gerrit java with all the java options so it can be called # like a normal CLI app gerrit-cli = pkgs.writeShellScriptBin "gerrit" '' @@ -106,6 +110,15 @@ in ''; }; + replicationSettings = mkOption { + type = gitIniType; + default = {}; + description = '' + Replication configuration. This will be generated to the + <literal>etc/replication.config</literal> file. + ''; + }; + plugins = mkOption { type = types.listOf types.package; default = []; @@ -138,6 +151,13 @@ in config = mkIf cfg.enable { + assertions = [ + { + assertion = cfg.replicationSettings != {} -> elem "replication" cfg.builtinPlugins; + message = "Gerrit replicationSettings require enabling the replication plugin"; + } + ]; + services.gerrit.settings = { cache.directory = "/var/cache/gerrit"; container.heapLimit = cfg.jvmHeapLimit; @@ -194,6 +214,7 @@ in # copy the config, keep it mutable because Gerrit ln -sfv ${gerritConfig} etc/gerrit.config + ln -sfv ${replicationConfig} etc/replication.config # install the plugins rm -rf plugins diff --git a/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix b/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix new file mode 100644 index 00000000000..2df762882fa --- /dev/null +++ b/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix @@ -0,0 +1,334 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.jitsi-meet; + + # The configuration files are JS of format "var <<string>> = <<JSON>>;". In order to + # override only some settings, we need to extract the JSON, use jq to merge it with + # the config provided by user, and then reconstruct the file. + overrideJs = + source: varName: userCfg: appendExtra: + let + extractor = pkgs.writeText "extractor.js" '' + var fs = require("fs"); + eval(fs.readFileSync(process.argv[2], 'utf8')); + process.stdout.write(JSON.stringify(eval(process.argv[3]))); + ''; + userJson = pkgs.writeText "user.json" (builtins.toJSON userCfg); + in (pkgs.runCommand "${varName}.js" { } '' + ${pkgs.nodejs}/bin/node ${extractor} ${source} ${varName} > default.json + ( + echo "var ${varName} = " + ${pkgs.jq}/bin/jq -s '.[0] * .[1]' default.json ${userJson} + echo ";" + echo ${escapeShellArg appendExtra} + ) > $out + ''); + + # Essential config - it's probably not good to have these as option default because + # types.attrs doesn't do merging. Let's merge explicitly, can still be overriden if + # user desires. + defaultCfg = { + hosts = { + domain = cfg.hostName; + muc = "conference.${cfg.hostName}"; + focus = "focus.${cfg.hostName}"; + }; + bosh = "//${cfg.hostName}/http-bind"; + }; +in +{ + options.services.jitsi-meet = with types; { + enable = mkEnableOption "Jitsi Meet - Secure, Simple and Scalable Video Conferences"; + + hostName = mkOption { + type = str; + example = "meet.example.org"; + description = '' + Hostname of the Jitsi Meet instance. + ''; + }; + + config = mkOption { + type = attrs; + default = { }; + example = literalExample '' + { + enableWelcomePage = false; + defaultLang = "fi"; + } + ''; + description = '' + Client-side web application settings that override the defaults in <filename>config.js</filename>. + + See <link xlink:href="https://github.com/jitsi/jitsi-meet/blob/master/config.js" /> for default + configuration with comments. + ''; + }; + + extraConfig = mkOption { + type = lines; + default = ""; + description = '' + Text to append to <filename>config.js</filename> web application config file. + + Can be used to insert JavaScript logic to determine user's region in cascading bridges setup. + ''; + }; + + interfaceConfig = mkOption { + type = attrs; + default = { }; + example = literalExample '' + { + SHOW_JITSI_WATERMARK = false; + SHOW_WATERMARK_FOR_GUESTS = false; + } + ''; + description = '' + Client-side web-app interface settings that override the defaults in <filename>interface_config.js</filename>. + + See <link xlink:href="https://github.com/jitsi/jitsi-meet/blob/master/interface_config.js" /> for + default configuration with comments. + ''; + }; + + videobridge = { + enable = mkOption { + type = bool; + default = true; + description = '' + Whether to enable Jitsi Videobridge instance and configure it to connect to Prosody. + + Additional configuration is possible with <option>services.jitsi-videobridge</option>. + ''; + }; + + passwordFile = mkOption { + type = nullOr str; + default = null; + example = "/run/keys/videobridge"; + description = '' + File containing password to the Prosody account for videobridge. + + If <literal>null</literal>, a file with password will be generated automatically. Setting + this option is useful if you plan to connect additional videobridges to the XMPP server. + ''; + }; + }; + + jicofo.enable = mkOption { + type = bool; + default = true; + description = '' + Whether to enable JiCoFo instance and configure it to connect to Prosody. + + Additional configuration is possible with <option>services.jicofo</option>. + ''; + }; + + nginx.enable = mkOption { + type = bool; + default = true; + description = '' + Whether to enable nginx virtual host that will serve the javascript application and act as + a proxy for the XMPP server. Further nginx configuration can be done by adapting + <option>services.nginx.virtualHosts.<hostName></option>. + When this is enabled, ACME will be used to retrieve a TLS certificate by default. To disable + this, set the <option>services.nginx.virtualHosts.<hostName>.enableACME</option> to + <literal>false</literal> and if appropriate do the same for + <option>services.nginx.virtualHosts.<hostName>.forceSSL</option>. + ''; + }; + + prosody.enable = mkOption { + type = bool; + default = true; + description = '' + Whether to configure Prosody to relay XMPP messages between Jitsi Meet components. Turn this + off if you want to configure it manually. + ''; + }; + }; + + config = mkIf cfg.enable { + services.prosody = mkIf cfg.prosody.enable { + enable = mkDefault true; + xmppComplianceSuite = mkDefault false; + modules = { + admin_adhoc = mkDefault false; + bosh = mkDefault true; + ping = mkDefault true; + roster = mkDefault true; + saslauth = mkDefault true; + tls = mkDefault true; + }; + muc = [ + { + domain = "conference.${cfg.hostName}"; + name = "Jitsi Meet MUC"; + roomLocking = false; + roomDefaultPublicJids = true; + extraConfig = '' + storage = "memory" + ''; + } + { + domain = "internal.${cfg.hostName}"; + name = "Jitsi Meet Videobridge MUC"; + extraConfig = '' + storage = "memory" + admins = { "focus@auth.${cfg.hostName}", "jvb@auth.${cfg.hostName}" } + ''; + #-- muc_room_cache_size = 1000 + } + ]; + extraModules = [ "pubsub" ]; + extraConfig = mkAfter '' + Component "focus.${cfg.hostName}" + component_secret = os.getenv("JICOFO_COMPONENT_SECRET") + ''; + virtualHosts.${cfg.hostName} = { + enabled = true; + domain = cfg.hostName; + extraConfig = '' + authentication = "anonymous" + c2s_require_encryption = false + admins = { "focus@auth.${cfg.hostName}" } + ''; + ssl = { + cert = "/var/lib/jitsi-meet/jitsi-meet.crt"; + key = "/var/lib/jitsi-meet/jitsi-meet.key"; + }; + }; + virtualHosts."auth.${cfg.hostName}" = { + enabled = true; + domain = "auth.${cfg.hostName}"; + extraConfig = '' + authentication = "internal_plain" + ''; + ssl = { + cert = "/var/lib/jitsi-meet/jitsi-meet.crt"; + key = "/var/lib/jitsi-meet/jitsi-meet.key"; + }; + }; + }; + systemd.services.prosody.serviceConfig = mkIf cfg.prosody.enable { + EnvironmentFile = [ "/var/lib/jitsi-meet/secrets-env" ]; + SupplementaryGroups = [ "jitsi-meet" ]; + }; + + users.groups.jitsi-meet = {}; + systemd.tmpfiles.rules = [ + "d '/var/lib/jitsi-meet' 0750 root jitsi-meet - -" + ]; + + systemd.services.jitsi-meet-init-secrets = { + wantedBy = [ "multi-user.target" ]; + before = [ "jicofo.service" "jitsi-videobridge2.service" ] ++ (optional cfg.prosody.enable "prosody.service"); + serviceConfig = { + Type = "oneshot"; + }; + + script = let + secrets = [ "jicofo-component-secret" "jicofo-user-secret" ] ++ (optional (cfg.videobridge.passwordFile == null) "videobridge-secret"); + videobridgeSecret = if cfg.videobridge.passwordFile != null then cfg.videobridge.passwordFile else "/var/lib/jitsi-meet/videobridge-secret"; + in + '' + cd /var/lib/jitsi-meet + ${concatMapStringsSep "\n" (s: '' + if [ ! -f ${s} ]; then + tr -dc a-zA-Z0-9 </dev/urandom | head -c 64 > ${s} + chown root:jitsi-meet ${s} + chmod 640 ${s} + fi + '') secrets} + + # for easy access in prosody + echo "JICOFO_COMPONENT_SECRET=$(cat jicofo-component-secret)" > secrets-env + chown root:jitsi-meet secrets-env + chmod 640 secrets-env + '' + + optionalString cfg.prosody.enable '' + ${config.services.prosody.package}/bin/prosodyctl register focus auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jicofo-user-secret)" + ${config.services.prosody.package}/bin/prosodyctl register jvb auth.${cfg.hostName} "$(cat ${videobridgeSecret})" + + # generate self-signed certificates + if [ ! -f /var/lib/jitsi-meet.crt ]; then + ${getBin pkgs.openssl}/bin/openssl req \ + -x509 \ + -newkey rsa:4096 \ + -keyout /var/lib/jitsi-meet/jitsi-meet.key \ + -out /var/lib/jitsi-meet/jitsi-meet.crt \ + -days 36500 \ + -nodes \ + -subj '/CN=${cfg.hostName}/CN=auth.${cfg.hostName}' + chmod 640 /var/lib/jitsi-meet/jitsi-meet.{crt,key} + chown root:jitsi-meet /var/lib/jitsi-meet/jitsi-meet.{crt,key} + fi + ''; + }; + + services.nginx = mkIf cfg.nginx.enable { + enable = mkDefault true; + virtualHosts.${cfg.hostName} = { + enableACME = mkDefault true; + forceSSL = mkDefault true; + root = pkgs.jitsi-meet; + extraConfig = '' + ssi on; + ''; + locations."@root_path".extraConfig = '' + rewrite ^/(.*)$ / break; + ''; + locations."~ ^/([^/\\?&:'\"]+)$".tryFiles = "$uri @root_path"; + locations."=/http-bind" = { + proxyPass = "http://localhost:5280/http-bind"; + extraConfig = '' + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + ''; + }; + locations."=/external_api.js" = mkDefault { + alias = "${pkgs.jitsi-meet}/libs/external_api.min.js"; + }; + locations."=/config.js" = mkDefault { + alias = overrideJs "${pkgs.jitsi-meet}/config.js" "config" (recursiveUpdate defaultCfg cfg.config) cfg.extraConfig; + }; + locations."=/interface_config.js" = mkDefault { + alias = overrideJs "${pkgs.jitsi-meet}/interface_config.js" "interfaceConfig" cfg.interfaceConfig ""; + }; + }; + }; + + services.jitsi-videobridge = mkIf cfg.videobridge.enable { + enable = true; + xmppConfigs."localhost" = { + userName = "jvb"; + domain = "auth.${cfg.hostName}"; + passwordFile = "/var/lib/jitsi-meet/videobridge-secret"; + mucJids = "jvbbrewery@internal.${cfg.hostName}"; + disableCertificateVerification = true; + }; + }; + + services.jicofo = mkIf cfg.jicofo.enable { + enable = true; + xmppHost = "localhost"; + xmppDomain = cfg.hostName; + userDomain = "auth.${cfg.hostName}"; + userName = "focus"; + userPasswordFile = "/var/lib/jitsi-meet/jicofo-user-secret"; + componentPasswordFile = "/var/lib/jitsi-meet/jicofo-component-secret"; + bridgeMuc = "jvbbrewery@internal.${cfg.hostName}"; + config = { + "org.jitsi.jicofo.ALWAYS_TRUST_MODE_ENABLED" = "true"; + }; + }; + }; + + meta.doc = ./jitsi-meet.xml; + meta.maintainers = lib.teams.jitsi.members; +} diff --git a/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.xml b/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.xml new file mode 100644 index 00000000000..97373bc6d9a --- /dev/null +++ b/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.xml @@ -0,0 +1,55 @@ +<chapter xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="module-services-jitsi-meet"> + <title>Jitsi Meet</title> + <para> + With Jitsi Meet on NixOS you can quickly configure a complete, + private, self-hosted video conferencing solution. + </para> + + <section xml:id="module-services-jitsi-basic-usage"> + <title>Basic usage</title> + <para> + A minimal configuration using Let's Encrypt for TLS certificates looks like this: +<programlisting>{ + services.jitsi-meet = { + <link linkend="opt-services.jitsi-meet.enable">enable</link> = true; + <link linkend="opt-services.jitsi-meet.enable">hostName</link> = "jitsi.example.com"; + }; + <link linkend="opt-services.jitsi-videobridge.openFirewall">services.jitsi-videobridge.openFirewall</link> = true; + <link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ]; + <link linkend="opt-security.acme.email">security.acme.email</link> = "me@example.com"; + <link linkend="opt-security.acme.acceptTerms">security.acme.acceptTerms</link> = true; +}</programlisting> + </para> + </section> + + <section xml:id="module-services-jitsi-configuration"> + <title>Configuration</title> + <para> + Here is the minimal configuration with additional configurations: +<programlisting>{ + services.jitsi-meet = { + <link linkend="opt-services.jitsi-meet.enable">enable</link> = true; + <link linkend="opt-services.jitsi-meet.enable">hostName</link> = "jitsi.example.com"; + <link linkend="opt-services.jitsi-meet.config">config</link> = { + enableWelcomePage = false; + prejoinPageEnabled = true; + defaultLang = "fi"; + }; + <link linkend="opt-services.jitsi-meet.interfaceConfig">interfaceConfig</link> = { + SHOW_JITSI_WATERMARK = false; + SHOW_WATERMARK_FOR_GUESTS = false; + }; + }; + <link linkend="opt-services.jitsi-videobridge.openFirewall">services.jitsi-videobridge.openFirewall</link> = true; + <link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ]; + <link linkend="opt-security.acme.email">security.acme.email</link> = "me@example.com"; + <link linkend="opt-security.acme.acceptTerms">security.acme.acceptTerms</link> = true; +}</programlisting> + </para> + </section> + +</chapter> diff --git a/nixpkgs/nixos/modules/services/web-apps/moodle.nix b/nixpkgs/nixos/modules/services/web-apps/moodle.nix index 1196780cf6e..f45eaa24d54 100644 --- a/nixpkgs/nixos/modules/services/web-apps/moodle.nix +++ b/nixpkgs/nixos/modules/services/web-apps/moodle.nix @@ -40,7 +40,7 @@ let $CFG->disableupdateautodeploy = true; $CFG->pathtogs = '${pkgs.ghostscript}/bin/gs'; - $CFG->pathtophp = '${pkgs.php}/bin/php'; + $CFG->pathtophp = '${phpExt}/bin/php'; $CFG->pathtodu = '${pkgs.coreutils}/bin/du'; $CFG->aspellpath = '${pkgs.aspell}/bin/aspell'; $CFG->pathtodot = '${pkgs.graphviz}/bin/dot'; @@ -55,6 +55,9 @@ let mysqlLocal = cfg.database.createLocally && cfg.database.type == "mysql"; pgsqlLocal = cfg.database.createLocally && cfg.database.type == "pgsql"; + + phpExt = pkgs.php.withExtensions + ({ enabled, all }: with all; [ iconv mbstring curl openssl tokenizer xmlrpc soap ctype zip gd simplexml dom intl json sqlite3 pgsql pdo_sqlite pdo_pgsql pdo_odbc pdo_mysql pdo mysqli session zlib xmlreader fileinfo ]); in { # interface @@ -222,6 +225,7 @@ in services.phpfpm.pools.moodle = { inherit user group; + phpPackage = phpExt; phpEnv.MOODLE_CONFIG = "${moodleConfig}"; phpOptions = '' zend_extension = opcache.so @@ -263,13 +267,13 @@ in after = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service"; environment.MOODLE_CONFIG = moodleConfig; script = '' - ${pkgs.php}/bin/php ${cfg.package}/share/moodle/admin/cli/check_database_schema.php && rc=$? || rc=$? + ${phpExt}/bin/php ${cfg.package}/share/moodle/admin/cli/check_database_schema.php && rc=$? || rc=$? - [ "$rc" == 1 ] && ${pkgs.php}/bin/php ${cfg.package}/share/moodle/admin/cli/upgrade.php \ + [ "$rc" == 1 ] && ${phpExt}/bin/php ${cfg.package}/share/moodle/admin/cli/upgrade.php \ --non-interactive \ --allow-unstable - [ "$rc" == 2 ] && ${pkgs.php}/bin/php ${cfg.package}/share/moodle/admin/cli/install_database.php \ + [ "$rc" == 2 ] && ${phpExt}/bin/php ${cfg.package}/share/moodle/admin/cli/install_database.php \ --agree-license \ --adminpass=${cfg.initialPassword} @@ -289,7 +293,7 @@ in serviceConfig = { User = user; Group = group; - ExecStart = "${pkgs.php}/bin/php ${cfg.package}/share/moodle/admin/cli/cron.php"; + ExecStart = "${phpExt}/bin/php ${cfg.package}/share/moodle/admin/cli/cron.php"; }; }; diff --git a/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix b/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix index f826096bf60..7da119758fc 100644 --- a/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix +++ b/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix @@ -34,7 +34,7 @@ let cd ${cfg.package} sudo=exec if [[ "$USER" != nextcloud ]]; then - sudo='exec /run/wrappers/bin/sudo -u nextcloud --preserve-env=NEXTCLOUD_CONFIG_DIR' + sudo='exec /run/wrappers/bin/sudo -u nextcloud --preserve-env=NEXTCLOUD_CONFIG_DIR --preserve-env=OC_PASS' fi export NEXTCLOUD_CONFIG_DIR="${cfg.home}/config" $sudo \ @@ -45,6 +45,22 @@ let inherit (config.system) stateVersion; in { + + imports = [ + (mkRemovedOptionModule [ "services" "nextcloud" "nginx" "enable" ] '' + The nextcloud module supports `nginx` as reverse-proxy by default and doesn't + support other reverse-proxies officially. + + However it's possible to use an alternative reverse-proxy by + + * disabling nginx + * setting `listen.owner` & `listen.group` in the phpfpm-pool to a different value + + Further details about this can be found in the `Nextcloud`-section of the NixOS-manual + (which can be openend e.g. by running `nixos-help`). + '') + ]; + options.services.nextcloud = { enable = mkEnableOption "nextcloud"; hostName = mkOption { @@ -69,7 +85,7 @@ in { package = mkOption { type = types.package; description = "Which package to use for the Nextcloud instance."; - relatedPackages = [ "nextcloud17" "nextcloud18" ]; + relatedPackages = [ "nextcloud17" "nextcloud18" "nextcloud19" ]; }; maxUploadSize = mkOption { @@ -91,16 +107,6 @@ in { ''; }; - nginx.enable = mkOption { - type = types.bool; - default = false; - description = '' - Whether to enable nginx virtual host management. - Further nginx configuration can be done by adapting <literal>services.nginx.virtualHosts.<name></literal>. - See <xref linkend="opt-services.nginx.virtualHosts"/> for further information. - ''; - }; - webfinger = mkOption { type = types.bool; default = false; @@ -303,6 +309,14 @@ in { ''; }; }; + occ = mkOption { + type = types.package; + default = occ; + internal = true; + description = '' + The nextcloud-occ program preconfigured to target this Nextcloud instance. + ''; + }; }; config = mkIf cfg.enable (mkMerge [ @@ -336,7 +350,16 @@ in { server, and wait until the upgrade to 17 is finished. Then, set `services.nextcloud.package` to `pkgs.nextcloud18` to upgrade to - Nextcloud version 18. + Nextcloud version 18. Please note that Nextcloud 19 is already out and it's + recommended to upgrade to nextcloud19 after that. + '') + ++ (optional (versionOlder cfg.package.version "19") '' + A legacy Nextcloud install (from before NixOS 20.09/unstable) may be installed. + + If/After nextcloud18 is installed successfully, you can safely upgrade to + nextcloud19. If not, please upgrade to nextcloud18 first since Nextcloud doesn't + support upgrades that skip multiple versions (i.e. an upgrade from 17 to 19 isn't + possible, but an upgrade from 18 to 19). ''); services.nextcloud.package = with pkgs; @@ -348,7 +371,8 @@ in { `pkgs.nextcloud`. '' else if versionOlder stateVersion "20.03" then nextcloud17 - else nextcloud18 + else if versionOlder stateVersion "20.09" then nextcloud18 + else nextcloud19 ); } @@ -360,6 +384,11 @@ in { }; 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 = [ cfg.package ]; + nextcloud-setup = let c = cfg.config; writePhpArrary = a: "[${concatMapStringsSep "," (val: ''"${toString val}"'') a}]"; @@ -445,10 +474,18 @@ in { script = '' chmod og+x ${cfg.home} ln -sf ${cfg.package}/apps ${cfg.home}/ - mkdir -p ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps - ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php - chown -R nextcloud:nginx ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps + # create nextcloud directories. + # if the directories exist already with wrong permissions, we fix that + for dir in ${cfg.home}/config ${cfg.home}/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} ${cfg.home}/config/override.config.php # Do not install if already installed if [[ ! -e ${cfg.home}/config/config.php ]]; then @@ -461,6 +498,7 @@ in { ${occSetTrustedDomainsCmd} ''; serviceConfig.Type = "oneshot"; + serviceConfig.User = "nextcloud"; }; nextcloud-cron = { environment.NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config"; @@ -479,7 +517,7 @@ in { services.phpfpm = { pools.nextcloud = { user = "nextcloud"; - group = "nginx"; + group = "nextcloud"; phpOptions = phpOptionsStr; phpPackage = phpPackage; phpEnv = { @@ -487,128 +525,121 @@ in { PATH = "/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin"; }; settings = mapAttrs (name: mkDefault) { - "listen.owner" = "nginx"; - "listen.group" = "nginx"; + "listen.owner" = config.services.nginx.user; + "listen.group" = config.services.nginx.group; } // cfg.poolSettings; extraConfig = cfg.poolConfig; }; }; - users.extraUsers.nextcloud = { + users.users.nextcloud = { home = "${cfg.home}"; - group = "nginx"; + group = "nextcloud"; createHome = true; }; + users.groups.nextcloud.members = [ "nextcloud" config.services.nginx.user ]; environment.systemPackages = [ occ ]; - } - (mkIf cfg.nginx.enable { - services.nginx = { - enable = true; - virtualHosts = { - ${cfg.hostName} = { - root = cfg.package; - locations = { - "= /robots.txt" = { - priority = 100; - extraConfig = '' - allow all; - log_not_found off; - access_log off; - ''; - }; - "/" = { - priority = 200; - extraConfig = "rewrite ^ /index.php;"; - }; - "~ ^/store-apps" = { - priority = 201; - extraConfig = "root ${cfg.home};"; - }; - "= /.well-known/carddav" = { - priority = 210; - extraConfig = "return 301 $scheme://$host/remote.php/dav;"; - }; - "= /.well-known/caldav" = { - priority = 210; - extraConfig = "return 301 $scheme://$host/remote.php/dav;"; - }; - "~ ^\\/(?:build|tests|config|lib|3rdparty|templates|data)\\/" = { - priority = 300; - extraConfig = "deny all;"; - }; - "~ ^\\/(?:\\.|autotest|occ|issue|indie|db_|console)" = { - priority = 300; - extraConfig = "deny all;"; - }; - "~ ^\\/(?:index|remote|public|cron|core/ajax\\/update|status|ocs\\/v[12]|updater\\/.+|ocs-provider\\/.+|ocm-provider\\/.+)\\.php(?:$|\\/)" = { - priority = 500; - extraConfig = '' - include ${config.services.nginx.package}/conf/fastcgi.conf; - fastcgi_split_path_info ^(.+\.php)(\\/.*)$; - try_files $fastcgi_script_name =404; - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_param HTTPS ${if cfg.https then "on" else "off"}; - fastcgi_param modHeadersAvailable true; - fastcgi_param front_controller_active true; - fastcgi_pass unix:${fpm.socket}; - fastcgi_intercept_errors on; - fastcgi_request_buffering off; - fastcgi_read_timeout 120s; - ''; - }; - "~ ^\\/(?:updater|ocs-provider|ocm-provider)(?:$|\\/)".extraConfig = '' - try_files $uri/ =404; - index index.php; - ''; - "~ \\.(?:css|js|woff2?|svg|gif)$".extraConfig = '' - try_files $uri /index.php$request_uri; - add_header Cache-Control "public, max-age=15778463"; - add_header X-Content-Type-Options nosniff; - add_header X-XSS-Protection "1; mode=block"; - add_header X-Robots-Tag none; - add_header X-Download-Options noopen; - add_header X-Permitted-Cross-Domain-Policies none; - add_header X-Frame-Options sameorigin; - add_header Referrer-Policy no-referrer; - access_log off; - ''; - "~ \\.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$".extraConfig = '' - try_files $uri /index.php$request_uri; - access_log off; - ''; - }; + services.nginx.enable = mkDefault true; + services.nginx.virtualHosts.${cfg.hostName} = { + root = cfg.package; + locations = { + "= /robots.txt" = { + priority = 100; + extraConfig = '' + allow all; + log_not_found off; + access_log off; + ''; + }; + "/" = { + priority = 900; + extraConfig = "try_files $uri $uri/ /index.php$request_uri;"; + }; + "~ ^/store-apps" = { + priority = 201; + extraConfig = "root ${cfg.home};"; + }; + "^~ /.well-known" = { + priority = 210; + extraConfig = '' + location = /.well-known/carddav { + return 301 $scheme://$host/remote.php/dav; + } + location = /.well-known/caldav { + return 301 $scheme://$host/remote.php/dav; + } + try_files $uri $uri/ =404; + ''; + }; + "~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)".extraConfig = '' + return 404; + ''; + "~ ^/(?:\\.|autotest|occ|issue|indie|db_|console)".extraConfig = '' + return 404; + ''; + "~ \\.php(?:$|/)" = { + priority = 500; extraConfig = '' - add_header X-Content-Type-Options nosniff; - add_header X-XSS-Protection "1; mode=block"; - add_header X-Robots-Tag none; - add_header X-Download-Options noopen; - add_header X-Permitted-Cross-Domain-Policies none; - add_header X-Frame-Options sameorigin; - add_header Referrer-Policy no-referrer; - add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; - error_page 403 /core/templates/403.php; - error_page 404 /core/templates/404.php; - client_max_body_size ${cfg.maxUploadSize}; - fastcgi_buffers 64 4K; - fastcgi_hide_header X-Powered-By; - gzip on; - gzip_vary on; - gzip_comp_level 4; - gzip_min_length 256; - gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; - gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; - - ${optionalString cfg.webfinger '' - rewrite ^/.well-known/host-meta /public.php?service=host-meta last; - rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; - ''} + include ${config.services.nginx.package}/conf/fastcgi.conf; + fastcgi_split_path_info ^(.+?\.php)(\\/.*)$; + set $path_info $fastcgi_path_info; + try_files $fastcgi_script_name =404; + fastcgi_param PATH_INFO $path_info; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param HTTPS ${if cfg.https then "on" else "off"}; + fastcgi_param modHeadersAvailable true; + fastcgi_param front_controller_active true; + fastcgi_pass unix:${fpm.socket}; + fastcgi_intercept_errors on; + fastcgi_request_buffering off; + fastcgi_read_timeout 120s; ''; }; + "~ \\.(?:css|js|svg|gif|map)$".extraConfig = '' + try_files $uri /index.php$request_uri; + expires 6M; + access_log off; + ''; + "~ \\.woff2?$".extraConfig = '' + try_files $uri /index.php$request_uri; + expires 7d; + access_log off; + ''; + "~ ^\\/(?:updater|ocs-provider|ocm-provider)(?:$|\\/)".extraConfig = '' + try_files $uri/ =404; + index index.php; + ''; }; + extraConfig = '' + index index.php index.html /index.php$request_uri; + expires 1m; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Robots-Tag none; + add_header X-Download-Options noopen; + add_header X-Permitted-Cross-Domain-Policies none; + add_header X-Frame-Options sameorigin; + add_header Referrer-Policy no-referrer; + add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; + client_max_body_size ${cfg.maxUploadSize}; + fastcgi_buffers 64 4K; + fastcgi_hide_header X-Powered-By; + gzip on; + gzip_vary on; + gzip_comp_level 4; + gzip_min_length 256; + gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; + gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; + + ${optionalString cfg.webfinger '' + rewrite ^/.well-known/host-meta /public.php?service=host-meta last; + rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; + ''} + ''; }; - }) + } ]); meta.doc = ./nextcloud.xml; diff --git a/nixpkgs/nixos/modules/services/web-apps/nextcloud.xml b/nixpkgs/nixos/modules/services/web-apps/nextcloud.xml index fc454f8ba25..02e4dba2861 100644 --- a/nixpkgs/nixos/modules/services/web-apps/nextcloud.xml +++ b/nixpkgs/nixos/modules/services/web-apps/nextcloud.xml @@ -29,7 +29,6 @@ services.nextcloud = { <link linkend="opt-services.nextcloud.enable">enable</link> = true; <link linkend="opt-services.nextcloud.hostName">hostName</link> = "nextcloud.tld"; - <link linkend="opt-services.nextcloud.nginx.enable">nginx.enable</link> = true; config = { <link linkend="opt-services.nextcloud.config.dbtype">dbtype</link> = "pgsql"; <link linkend="opt-services.nextcloud.config.dbuser">dbuser</link> = "nextcloud"; @@ -61,9 +60,8 @@ </para> <para> - The options <literal>hostName</literal> and <literal>nginx.enable</literal> - are used internally to configure an HTTP server using - <literal><link xlink:href="https://php-fpm.org/">PHP-FPM</link></literal> + The <literal>hostName</literal> option is used internally to configure an HTTP + server using <literal><link xlink:href="https://php-fpm.org/">PHP-FPM</link></literal> and <literal>nginx</literal>. The <literal>config</literal> attribute set is used by the imperative installer and all values are written to an additional file to ensure that changes can be applied by changing the module's options. @@ -125,6 +123,61 @@ </para> </section> + <section xml:id="module-services-nextcloud-httpd"> + <title>Using an alternative webserver as reverse-proxy (e.g. <literal>httpd</literal>)</title> + <para> + By default, <package>nginx</package> is used as reverse-proxy for <package>nextcloud</package>. + However, it's possible to use e.g. <package>httpd</package> by explicitly disabling + <package>nginx</package> using <xref linkend="opt-services.nginx.enable" /> and fixing the + settings <literal>listen.owner</literal> & <literal>listen.group</literal> in the + <link linkend="opt-services.phpfpm.pools">corresponding <literal>phpfpm</literal> pool</link>. + </para> + <para> + An exemplary configuration may look like this: +<programlisting>{ config, lib, pkgs, ... }: { + <link linkend="opt-services.nginx.enable">services.nginx.enable</link> = false; + services.nextcloud = { + <link linkend="opt-services.nextcloud.enable">enable</link> = true; + <link linkend="opt-services.nextcloud.hostName">hostName</link> = "localhost"; + + /* further, required options */ + }; + <link linkend="opt-services.phpfpm.pools._name_.settings">services.phpfpm.pools.nextcloud.settings</link> = { + "listen.owner" = config.services.httpd.user; + "listen.group" = config.services.httpd.group; + }; + services.httpd = { + <link linkend="opt-services.httpd.enable">enable</link> = true; + <link linkend="opt-services.httpd.adminAddr">adminAddr</link> = "webmaster@localhost"; + <link linkend="opt-services.httpd.extraModules">extraModules</link> = [ "proxy_fcgi" ]; + virtualHosts."localhost" = { + <link linkend="opt-services.httpd.virtualHosts._name_.documentRoot">documentRoot</link> = config.services.nextcloud.package; + <link linkend="opt-services.httpd.virtualHosts._name_.extraConfig">extraConfig</link> = '' + <Directory "${config.services.nextcloud.package}"> + <FilesMatch "\.php$"> + <If "-f %{REQUEST_FILENAME}"> + SetHandler "proxy:unix:${config.services.phpfpm.pools.nextcloud.socket}|fcgi://localhost/" + </If> + </FilesMatch> + <IfModule mod_rewrite.c> + RewriteEngine On + RewriteBase / + RewriteRule ^index\.php$ - [L] + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /index.php [L] + </IfModule> + DirectoryIndex index.php + Require all granted + Options +FollowSymLinks + </Directory> + ''; + }; + }; +}</programlisting> + </para> + </section> + <section xml:id="module-services-nextcloud-maintainer-info"> <title>Maintainer information</title> @@ -161,5 +214,11 @@ }; }</programlisting> </para> + + <para> + Ideally we should make sure that it's possible to jump two NixOS versions forward: + i.e. the warnings and the logic in the module should guard a user to upgrade from a + Nextcloud on e.g. 19.09 to a Nextcloud on 20.09. + </para> </section> </chapter> diff --git a/nixpkgs/nixos/modules/services/web-apps/pgpkeyserver-lite.nix b/nixpkgs/nixos/modules/services/web-apps/pgpkeyserver-lite.nix index ad70ba70bbe..838fd19ad29 100644 --- a/nixpkgs/nixos/modules/services/web-apps/pgpkeyserver-lite.nix +++ b/nixpkgs/nixos/modules/services/web-apps/pgpkeyserver-lite.nix @@ -33,7 +33,7 @@ in description = " Which hostname to set the vHost to that is proxying to sks. "; - }; + }; hkpAddress = mkOption { default = builtins.head sksCfg.hkpAddress; diff --git a/nixpkgs/nixos/modules/services/web-apps/rss-bridge.nix b/nixpkgs/nixos/modules/services/web-apps/rss-bridge.nix new file mode 100644 index 00000000000..f1d5b7660f3 --- /dev/null +++ b/nixpkgs/nixos/modules/services/web-apps/rss-bridge.nix @@ -0,0 +1,127 @@ +{ config, lib, pkgs, ... }: +with lib; +let + cfg = config.services.rss-bridge; + + poolName = "rss-bridge"; + + whitelist = pkgs.writeText "rss-bridge_whitelist.txt" + (concatStringsSep "\n" cfg.whitelist); +in +{ + options = { + services.rss-bridge = { + enable = mkEnableOption "rss-bridge"; + + user = mkOption { + type = types.str; + default = "nginx"; + example = "nginx"; + description = '' + User account under which both the service and the web-application run. + ''; + }; + + group = mkOption { + type = types.str; + default = "nginx"; + example = "nginx"; + description = '' + Group under which the web-application run. + ''; + }; + + pool = mkOption { + type = types.str; + default = poolName; + description = '' + Name of existing phpfpm pool that is used to run web-application. + If not specified a pool will be created automatically with + default values. + ''; + }; + + dataDir = mkOption { + type = types.str; + default = "/var/lib/rss-bridge"; + description = '' + Location in which cache directory will be created. + You can put <literal>config.ini.php</literal> in here. + ''; + }; + + virtualHost = mkOption { + type = types.nullOr types.str; + default = "rss-bridge"; + description = '' + Name of the nginx virtualhost to use and setup. If null, do not setup any virtualhost. + ''; + }; + + whitelist = mkOption { + type = types.listOf types.str; + default = []; + example = options.literalExample '' + [ + "Facebook" + "Instagram" + "Twitter" + ] + ''; + description = '' + List of bridges to be whitelisted. + If the list is empty, rss-bridge will use whitelist.default.txt. + Use <literal>[ "*" ]</literal> to whitelist all. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + services.phpfpm.pools = mkIf (cfg.pool == poolName) { + ${poolName} = { + user = cfg.user; + settings = mapAttrs (name: mkDefault) { + "listen.owner" = cfg.user; + "listen.group" = cfg.user; + "listen.mode" = "0600"; + "pm" = "dynamic"; + "pm.max_children" = 75; + "pm.start_servers" = 10; + "pm.min_spare_servers" = 5; + "pm.max_spare_servers" = 20; + "pm.max_requests" = 500; + "catch_workers_output" = 1; + }; + }; + }; + systemd.tmpfiles.rules = [ + "d '${cfg.dataDir}/cache' 0750 ${cfg.user} ${cfg.group} - -" + (mkIf (cfg.whitelist != []) "L+ ${cfg.dataDir}/whitelist.txt - - - - ${whitelist}") + "z '${cfg.dataDir}/config.ini.php' 0750 ${cfg.user} ${cfg.group} - -" + ]; + + services.nginx = mkIf (cfg.virtualHost != null) { + enable = true; + virtualHosts = { + ${cfg.virtualHost} = { + root = "${pkgs.rss-bridge}"; + + locations."/" = { + tryFiles = "$uri /index.php$is_args$args"; + }; + + locations."~ ^/index.php(/|$)" = { + extraConfig = '' + include ${pkgs.nginx}/conf/fastcgi_params; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:${config.services.phpfpm.pools.${cfg.pool}.socket}; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param RSSBRIDGE_DATA ${cfg.dataDir}; + ''; + }; + }; + }; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/web-apps/sogo.nix b/nixpkgs/nixos/modules/services/web-apps/sogo.nix index 5f30124dd68..4610bb96cb5 100644 --- a/nixpkgs/nixos/modules/services/web-apps/sogo.nix +++ b/nixpkgs/nixos/modules/services/web-apps/sogo.nix @@ -77,7 +77,6 @@ in { // Paths WOSendMail = "/run/wrappers/bin/sendmail"; SOGoMailSpoolPath = "/var/lib/sogo/spool"; - SOGoZipPath = "${pkgs.zip}/bin/zip"; // Enable CSRF protection SOGoXSRFValidationEnabled = YES; // Remove dates from log (jornald does that) diff --git a/nixpkgs/nixos/modules/services/web-apps/trilium.nix b/nixpkgs/nixos/modules/services/web-apps/trilium.nix index 6f47193c62b..3fa8dad0490 100644 --- a/nixpkgs/nixos/modules/services/web-apps/trilium.nix +++ b/nixpkgs/nixos/modules/services/web-apps/trilium.nix @@ -83,7 +83,7 @@ in }; }; - config = lib.mkIf cfg.enable (lib.mkMerge [ + config = lib.mkIf cfg.enable (lib.mkMerge [ { meta.maintainers = with lib.maintainers; [ kampka ]; diff --git a/nixpkgs/nixos/modules/services/web-apps/tt-rss.nix b/nixpkgs/nixos/modules/services/web-apps/tt-rss.nix index 2ea9537b93d..6a29f10d119 100644 --- a/nixpkgs/nixos/modules/services/web-apps/tt-rss.nix +++ b/nixpkgs/nixos/modules/services/web-apps/tt-rss.nix @@ -632,8 +632,6 @@ let User = "${cfg.user}"; Group = "tt_rss"; ExecStart = "${pkgs.php}/bin/php ${cfg.root}/update.php --daemon --quiet"; - StandardOutput = "syslog"; - StandardError = "syslog"; Restart = "on-failure"; RestartSec = "60"; SyslogIdentifier = "tt-rss"; |