about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/services/web-apps
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/services/web-apps')
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix38
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/keycloak.nix14
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/mattermost.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/mobilizon.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/nextcloud.md2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/nextcloud.nix22
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/node-red.nix2
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/windmill.nix177
-rw-r--r--nixpkgs/nixos/modules/services/web-apps/wordpress.nix2
9 files changed, 240 insertions, 21 deletions
diff --git a/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix b/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix
index 0c0eb66e65b7..c4505534d635 100644
--- a/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/jitsi-meet.nix
@@ -35,6 +35,7 @@ let
       domain = cfg.hostName;
       muc = "conference.${cfg.hostName}";
       focus = "focus.${cfg.hostName}";
+      jigasi = "jigasi.${cfg.hostName}";
     };
     bosh = "//${cfg.hostName}/http-bind";
     websocket = "wss://${cfg.hostName}/xmpp-websocket";
@@ -145,6 +146,16 @@ in
       '';
     };
 
+    jigasi.enable = mkOption {
+      type = bool;
+      default = false;
+      description = ''
+        Whether to enable jigasi instance and configure it to connect to Prosody.
+
+        Additional configuration is possible with <option>services.jigasi</option>.
+      '';
+    };
+
     nginx.enable = mkOption {
       type = bool;
       default = true;
@@ -224,7 +235,7 @@ in
           roomDefaultPublicJids = true;
           extraConfig = ''
             storage = "memory"
-            admins = { "focus@auth.${cfg.hostName}", "jvb@auth.${cfg.hostName}" }
+            admins = { "focus@auth.${cfg.hostName}", "jvb@auth.${cfg.hostName}", "jigasi@auth.${cfg.hostName}" }
           '';
           #-- muc_room_cache_size = 1000
         }
@@ -263,6 +274,9 @@ in
           Component "focus.${cfg.hostName}" "client_proxy"
             target_address = "focus@auth.${cfg.hostName}"
 
+          Component "jigasi.${cfg.hostName}" "client_proxy"
+            target_address = "jigasi@auth.${cfg.hostName}"
+
           Component "speakerstats.${cfg.hostName}" "speakerstats_component"
             muc_component = "conference.${cfg.hostName}"
 
@@ -356,7 +370,10 @@ in
         ${config.services.prosody.package}/bin/prosodyctl mod_roster_command subscribe focus.${cfg.hostName} focus@auth.${cfg.hostName}
         ${config.services.prosody.package}/bin/prosodyctl register jibri auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jibri-auth-secret)"
         ${config.services.prosody.package}/bin/prosodyctl register recorder recorder.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jibri-recorder-secret)"
+      '' + optionalString cfg.jigasi.enable ''
+        ${config.services.prosody.package}/bin/prosodyctl register jigasi auth.${cfg.hostName} "$(cat /var/lib/jitsi-meet/jigasi-user-secret)"
       '';
+
       serviceConfig = {
         EnvironmentFile = [ "/var/lib/jitsi-meet/secrets-env" ];
         SupplementaryGroups = [ "jitsi-meet" ];
@@ -371,13 +388,13 @@ in
 
     systemd.services.jitsi-meet-init-secrets = {
       wantedBy = [ "multi-user.target" ];
-      before = [ "jicofo.service" "jitsi-videobridge2.service" ] ++ (optional cfg.prosody.enable "prosody.service");
+      before = [ "jicofo.service" "jitsi-videobridge2.service" ] ++ (optional cfg.prosody.enable "prosody.service") ++ (optional cfg.jigasi.enable "jigasi.service");
       serviceConfig = {
         Type = "oneshot";
       };
 
       script = let
-        secrets = [ "jicofo-component-secret" "jicofo-user-secret" "jibri-auth-secret" "jibri-recorder-secret" ] ++ (optional (cfg.videobridge.passwordFile == null) "videobridge-secret");
+        secrets = [ "jicofo-component-secret" "jicofo-user-secret" "jibri-auth-secret" "jibri-recorder-secret" ] ++ (optionals cfg.jigasi.enable [ "jigasi-user-secret" "jigasi-component-secret" ]) ++ (optional (cfg.videobridge.passwordFile == null) "videobridge-secret");
       in
       ''
         cd /var/lib/jitsi-meet
@@ -391,6 +408,7 @@ in
 
         # for easy access in prosody
         echo "JICOFO_COMPONENT_SECRET=$(cat jicofo-component-secret)" > secrets-env
+        echo "JIGASI_COMPONENT_SECRET=$(cat jigasi-component-secret)" >> secrets-env
         chown root:jitsi-meet secrets-env
         chmod 640 secrets-env
       ''
@@ -592,6 +610,20 @@ in
         stripFromRoomDomain = "conference.";
       };
     };
+
+    services.jigasi = mkIf cfg.jigasi.enable {
+      enable = true;
+      xmppHost = "localhost";
+      xmppDomain = cfg.hostName;
+      userDomain = "auth.${cfg.hostName}";
+      userName = "jigasi";
+      userPasswordFile = "/var/lib/jitsi-meet/jigasi-user-secret";
+      componentPasswordFile = "/var/lib/jitsi-meet/jigasi-component-secret";
+      bridgeMuc = "jigasibrewery@internal.${cfg.hostName}";
+      config = {
+        "org.jitsi.jigasi.ALWAYS_TRUST_MODE_ENABLED" = "true";
+      };
+    };
   };
 
   meta.doc = ./jitsi-meet.md;
diff --git a/nixpkgs/nixos/modules/services/web-apps/keycloak.nix b/nixpkgs/nixos/modules/services/web-apps/keycloak.nix
index 5d44bdee64a7..6d2948913b19 100644
--- a/nixpkgs/nixos/modules/services/web-apps/keycloak.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/keycloak.nix
@@ -25,7 +25,6 @@ let
     maintainers
     catAttrs
     collect
-    splitString
     hasPrefix
     ;
 
@@ -329,7 +328,8 @@ in
             };
 
             hostname = mkOption {
-              type = str;
+              type = nullOr str;
+              default = null;
               example = "keycloak.example.com";
               description = lib.mdDoc ''
                 The hostname part of the public URL used as base for
@@ -451,7 +451,7 @@ in
 
       keycloakConfig = lib.generators.toKeyValue {
         mkKeyValue = lib.flip lib.generators.mkKeyValueDefault "=" {
-          mkValueString = v: with builtins;
+          mkValueString = v:
             if isInt v then toString v
             else if isString v then v
             else if true == v then "true"
@@ -480,6 +480,14 @@ in
             assertion = createLocalPostgreSQL -> config.services.postgresql.settings.standard_conforming_strings or true;
             message = "Setting up a local PostgreSQL db for Keycloak requires `standard_conforming_strings` turned on to work reliably";
           }
+          {
+            assertion = cfg.settings.hostname != null || cfg.settings.hostname-url or null != null;
+            message = "Setting the Keycloak hostname is required, see `services.keycloak.settings.hostname`";
+          }
+          {
+            assertion = !(cfg.settings.hostname != null && cfg.settings.hostname-url or null != null);
+            message = "`services.keycloak.settings.hostname` and `services.keycloak.settings.hostname-url` are mutually exclusive";
+          }
         ];
 
         environment.systemPackages = [ keycloakBuild ];
diff --git a/nixpkgs/nixos/modules/services/web-apps/mattermost.nix b/nixpkgs/nixos/modules/services/web-apps/mattermost.nix
index f19465eeb59a..503559432374 100644
--- a/nixpkgs/nixos/modules/services/web-apps/mattermost.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/mattermost.nix
@@ -102,7 +102,7 @@ in
     services.mattermost = {
       enable = mkEnableOption (lib.mdDoc "Mattermost chat server");
 
-      package = mkPackageOption pkgs "mattermostl" { };
+      package = mkPackageOption pkgs "mattermost" { };
 
       statePath = mkOption {
         type = types.str;
diff --git a/nixpkgs/nixos/modules/services/web-apps/mobilizon.nix b/nixpkgs/nixos/modules/services/web-apps/mobilizon.nix
index 0a530bff9232..bdb08f613149 100644
--- a/nixpkgs/nixos/modules/services/web-apps/mobilizon.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/mobilizon.nix
@@ -384,7 +384,7 @@ in
           ensureDBOwnership = false;
         }
       ];
-      extraPlugins = with postgresql.pkgs; [ postgis ];
+      extraPlugins = ps: with ps; [ postgis ];
     };
 
     # Nginx config taken from support/nginx/mobilizon-release.conf
diff --git a/nixpkgs/nixos/modules/services/web-apps/nextcloud.md b/nixpkgs/nixos/modules/services/web-apps/nextcloud.md
index ecc7f380592a..b10fd566abb3 100644
--- a/nixpkgs/nixos/modules/services/web-apps/nextcloud.md
+++ b/nixpkgs/nixos/modules/services/web-apps/nextcloud.md
@@ -5,7 +5,7 @@ self-hostable cloud platform. The server setup can be automated using
 [services.nextcloud](#opt-services.nextcloud.enable). A
 desktop client is packaged at `pkgs.nextcloud-client`.
 
-The current default by NixOS is `nextcloud27` which is also the latest
+The current default by NixOS is `nextcloud28` which is also the latest
 major version available.
 
 ## Basic usage {#module-services-nextcloud-basic-usage}
diff --git a/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix b/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
index 6c50ea3c81ef..2a3db4cd13f9 100644
--- a/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
@@ -28,6 +28,7 @@ let
   phpPackage = cfg.phpPackage.buildEnv {
     extensions = { enabled, all }:
       (with all; enabled
+        ++ [ bz2 intl sodium ] # recommended
         ++ optional cfg.enableImagemagick imagick
         # Optionally enabled depending on caching settings
         ++ optional cfg.caching.apcu apcu
@@ -61,7 +62,9 @@ let
   pgsqlLocal = cfg.database.createLocally && cfg.config.dbtype == "pgsql";
 
   # https://github.com/nextcloud/documentation/pull/11179
-  ocmProviderIsNotAStaticDirAnymore = versionAtLeast cfg.package.version "27.1.2";
+  ocmProviderIsNotAStaticDirAnymore = versionAtLeast cfg.package.version "27.1.2"
+    || (versionOlder cfg.package.version "27.0.0"
+      && versionAtLeast cfg.package.version "26.0.8");
 
 in {
 
@@ -188,7 +191,7 @@ in {
     package = mkOption {
       type = types.package;
       description = lib.mdDoc "Which package to use for the Nextcloud instance.";
-      relatedPackages = [ "nextcloud26" "nextcloud27" ];
+      relatedPackages = [ "nextcloud26" "nextcloud27" "nextcloud28" ];
     };
     phpPackage = mkPackageOption pkgs "php" {
       example = "php82";
@@ -238,7 +241,7 @@ in {
     };
 
     phpOptions = mkOption {
-      type = types.attrsOf types.str;
+      type = with types; attrsOf (oneOf [ str int ]);
       defaultText = literalExpression (generators.toPretty { } defaultPHPSettings);
       description = lib.mdDoc ''
         Options for PHP's php.ini file for nextcloud.
@@ -677,7 +680,7 @@ in {
 
   config = mkIf cfg.enable (mkMerge [
     { warnings = let
-        latest = 27;
+        latest = 28;
         upgradeWarning = major: nixos:
           ''
             A legacy Nextcloud install (from before NixOS ${nixos}) may be installed.
@@ -698,7 +701,8 @@ in {
         '')
         ++ (optional (versionOlder cfg.package.version "25") (upgradeWarning 24 "22.11"))
         ++ (optional (versionOlder cfg.package.version "26") (upgradeWarning 25 "23.05"))
-        ++ (optional (versionOlder cfg.package.version "27") (upgradeWarning 26 "23.11"));
+        ++ (optional (versionOlder cfg.package.version "27") (upgradeWarning 26 "23.11"))
+        ++ (optional (versionOlder cfg.package.version "28") (upgradeWarning 27 "24.05"));
 
       services.nextcloud.package = with pkgs;
         mkDefault (
@@ -708,15 +712,13 @@ in {
               nextcloud defined in an overlay, please set `services.nextcloud.package` to
               `pkgs.nextcloud`.
             ''
-          else if versionOlder stateVersion "22.11" then nextcloud24
           else if versionOlder stateVersion "23.05" then nextcloud25
           else if versionOlder stateVersion "23.11" then nextcloud26
-          else nextcloud27
+          else if versionOlder stateVersion "24.05" then nextcloud27
+          else nextcloud28
         );
 
-      services.nextcloud.phpPackage =
-        if versionOlder cfg.package.version "26" then pkgs.php81
-        else pkgs.php82;
+      services.nextcloud.phpPackage = pkgs.php82;
 
       services.nextcloud.phpOptions = mkMerge [
         (mapAttrs (const mkOptionDefault) defaultPHPSettings)
diff --git a/nixpkgs/nixos/modules/services/web-apps/node-red.nix b/nixpkgs/nixos/modules/services/web-apps/node-red.nix
index de78f05a98ca..7f265d289bdb 100644
--- a/nixpkgs/nixos/modules/services/web-apps/node-red.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/node-red.nix
@@ -19,7 +19,7 @@ in
   options.services.node-red = {
     enable = mkEnableOption (lib.mdDoc "the Node-RED service");
 
-    package = mkPackageOption pkgs "nodePackages.node-red" { };
+    package = mkPackageOption pkgs.nodePackages "node-red" { };
 
     openFirewall = mkOption {
       type = types.bool;
diff --git a/nixpkgs/nixos/modules/services/web-apps/windmill.nix b/nixpkgs/nixos/modules/services/web-apps/windmill.nix
new file mode 100644
index 000000000000..8e940dabdc1f
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/web-apps/windmill.nix
@@ -0,0 +1,177 @@
+{ config, pkgs, lib, ... }:
+
+let
+  cfg = config.services.windmill;
+in
+{
+  options.services.windmill = {
+    enable = lib.mkEnableOption (lib.mdDoc "windmill service");
+
+    serverPort = lib.mkOption {
+      type = lib.types.port;
+      default = 8001;
+      description = lib.mdDoc "Port the windmill server listens on.";
+    };
+
+    lspPort = lib.mkOption {
+      type = lib.types.port;
+      default = 3001;
+      description = lib.mdDoc "Port the windmill lsp listens on.";
+    };
+
+    database = {
+      name = lib.mkOption {
+        type = lib.types.str;
+        # the simplest database setup is to have the database named like the user.
+        default = "windmill";
+        description = lib.mdDoc "Database name.";
+      };
+
+      user = lib.mkOption {
+        type = lib.types.str;
+        # the simplest database setup is to have the database user like the name.
+        default = "windmill";
+        description = lib.mdDoc "Database user.";
+      };
+
+      urlPath = lib.mkOption {
+        type = lib.types.path;
+        description = lib.mdDoc ''
+          Path to the file containing the database url windmill should connect to. This is not deducted from database user and name as it might contain a secret
+        '';
+        example = "config.age.secrets.DATABASE_URL_FILE.path";
+      };
+      createLocally = lib.mkOption {
+        type = lib.types.bool;
+        default = true;
+        description = lib.mdDoc "Whether to create a local database automatically.";
+      };
+    };
+
+    baseUrl = lib.mkOption {
+      type = lib.types.str;
+      description = lib.mdDoc ''
+        The base url that windmill will be served on.
+      '';
+      example = "https://windmill.example.com";
+    };
+
+    logLevel = lib.mkOption {
+      type = lib.types.enum [ "error" "warn" "info" "debug" "trace" ];
+      default = "info";
+      description = lib.mdDoc "Log level";
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+
+    services.postgresql = lib.optionalAttrs (cfg.database.createLocally) {
+      enable = lib.mkDefault true;
+
+      ensureDatabases = [ cfg.database.name ];
+      ensureUsers = [
+        { name = cfg.database.user;
+          ensureDBOwnership = true;
+        }
+      ];
+
+   };
+
+   systemd.services =
+    let
+      serviceConfig = {
+        DynamicUser = true;
+        # using the same user to simplify db connection
+        User = cfg.database.user;
+        ExecStart = "${pkgs.windmill}/bin/windmill";
+
+        Restart = "always";
+        LoadCredential = [
+          "DATABASE_URL_FILE:${cfg.database.urlPath}"
+        ];
+      };
+    in
+    {
+
+    # coming from https://github.com/windmill-labs/windmill/blob/main/init-db-as-superuser.sql
+    # modified to not grant priviledges on all tables
+    # create role windmill_user and windmill_admin only if they don't exist
+    postgresql.postStart = lib.mkIf cfg.database.createLocally (lib.mkAfter ''
+      $PSQL -tA <<"EOF"
+DO $$
+BEGIN
+    IF NOT EXISTS (
+        SELECT FROM pg_catalog.pg_roles
+        WHERE rolname = 'windmill_user'
+    ) THEN
+        CREATE ROLE windmill_user;
+        GRANT ALL PRIVILEGES ON DATABASE ${cfg.database.name} TO windmill_user;
+    ELSE
+      RAISE NOTICE 'Role "windmill_user" already exists. Skipping.';
+    END IF;
+    IF NOT EXISTS (
+        SELECT FROM pg_catalog.pg_roles
+        WHERE rolname = 'windmill_admin'
+    ) THEN
+      CREATE ROLE windmill_admin WITH BYPASSRLS;
+      GRANT windmill_user TO windmill_admin;
+    ELSE
+      RAISE NOTICE 'Role "windmill_admin" already exists. Skipping.';
+    END IF;
+    GRANT windmill_admin TO windmill;
+END
+$$;
+EOF
+    '');
+
+     windmill-server = {
+        description = "Windmill server";
+        after = [ "network.target" ] ++ lib.optional cfg.database.createLocally "postgresql.service";
+        wantedBy = [ "multi-user.target" ];
+
+        serviceConfig = serviceConfig // { StateDirectory = "windmill";};
+
+        environment = {
+          DATABASE_URL_FILE = "%d/DATABASE_URL_FILE";
+          PORT = builtins.toString cfg.serverPort;
+          WM_BASE_URL = cfg.baseUrl;
+          RUST_LOG = cfg.logLevel;
+          MODE = "server";
+        };
+      };
+
+     windmill-worker = {
+        description = "Windmill worker";
+        after = [ "network.target" ] ++ lib.optional cfg.database.createLocally "postgresql.service";
+        wantedBy = [ "multi-user.target" ];
+
+        serviceConfig = serviceConfig // { StateDirectory = "windmill-worker";};
+
+        environment = {
+          DATABASE_URL_FILE = "%d/DATABASE_URL_FILE";
+          WM_BASE_URL = cfg.baseUrl;
+          RUST_LOG = cfg.logLevel;
+          MODE = "worker";
+          WORKER_GROUP = "default";
+          KEEP_JOB_DIR = "false";
+        };
+      };
+
+     windmill-worker-native = {
+        description = "Windmill worker native";
+        after = [ "network.target" ] ++ lib.optional cfg.database.createLocally "postgresql.service";
+        wantedBy = [ "multi-user.target" ];
+
+        serviceConfig = serviceConfig // { StateDirectory = "windmill-worker-native";};
+
+        environment = {
+          DATABASE_URL_FILE = "%d/DATABASE_URL_FILE";
+          WM_BASE_URL = cfg.baseUrl;
+          RUST_LOG = cfg.logLevel;
+          MODE = "worker";
+          WORKER_GROUP = "native";
+        };
+      };
+    };
+  };
+}
diff --git a/nixpkgs/nixos/modules/services/web-apps/wordpress.nix b/nixpkgs/nixos/modules/services/web-apps/wordpress.nix
index 03d5634854a3..002d6683b2ed 100644
--- a/nixpkgs/nixos/modules/services/web-apps/wordpress.nix
+++ b/nixpkgs/nixos/modules/services/web-apps/wordpress.nix
@@ -34,7 +34,7 @@ let
       # copy additional plugin(s), theme(s) and language(s)
       ${concatStringsSep "\n" (mapAttrsToList (name: theme: "cp -r ${theme} $out/share/wordpress/wp-content/themes/${name}") cfg.themes)}
       ${concatStringsSep "\n" (mapAttrsToList (name: plugin: "cp -r ${plugin} $out/share/wordpress/wp-content/plugins/${name}") cfg.plugins)}
-      ${concatMapStringsSep "\n" (language: "cp -r ${language}/* $out/share/wordpress/wp-content/languages/") cfg.languages}
+      ${concatMapStringsSep "\n" (language: "cp -r ${language} $out/share/wordpress/wp-content/languages/") cfg.languages}
     '';
   };