Unverified Commit fcf6662f authored by Jonas Heinrich's avatar Jonas Heinrich Committed by GitHub
Browse files

Merge pull request #229159 from Misterio77/refactor-nextcloud-createlocally

nixos/nextcloud: refactor database.createLocally
parents 1a0c498e fddf531c
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -217,6 +217,11 @@ In addition to numerous new and upgraded packages, this release has the followin

- The [services.wordpress.sites.<name>.plugins](#opt-services.wordpress.sites._name_.plugins) and [services.wordpress.sites.<name>.themes](#opt-services.wordpress.sites._name_.themes) options have been converted from sets to attribute sets to allow for consumers to specify explicit install paths via attribute name.

- [`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally) now uses socket authentication and is no longer compatible with password authentication.
  - If you want the module to manage the database for you, unset [`services.nextcloud.config.dbpassFile`](#opt-services.nextcloud.config.dbpassFile) (and [`services.nextcloud.config.dbhost`](#opt-services.nextcloud.config.dbhost), if it's set).
  - If your database is external, simply set [`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally) to `false`.
  - If you want to use password authentication **and** create the database locally, you will have to use [`services.mysql`](#opt-services.mysql.enable) to set it up.

- `protonmail-bridge` package has been updated to major version 3.

- Nebula now runs as a system user and group created for each nebula network, using the `CAP_NET_ADMIN` ambient capability on launch rather than starting as root. Ensure that any files each Nebula instance needs to access are owned by the correct user and group, by default `nebula-${networkName}`.
+10 −24
Original line number Diff line number Diff line
@@ -12,10 +12,16 @@ major version available.

Nextcloud is a PHP-based application which requires an HTTP server
([`services.nextcloud`](#opt-services.nextcloud.enable)
optionally supports
[`services.nginx`](#opt-services.nginx.enable))
and a database (it's recommended to use
[`services.postgresql`](#opt-services.postgresql.enable)).
and optionally supports
[`services.nginx`](#opt-services.nginx.enable)).

For the database, you can set
[`services.nextcloud.config.dbtype`](#opt-services.nextcloud.config.dbtype) to
either `sqlite` (the default), `mysql`, or `pgsql`. For the last two, by
default, a local database will be created and nextcloud will connect to it via
socket; this can be disabled by setting
[`services.nextcloud.database.createLocally`](#opt-services.nextcloud.database.createLocally)
to `false`.

A very basic configuration may look like this:
```
@@ -26,28 +32,8 @@ A very basic configuration may look like this:
    hostName = "nextcloud.tld";
    config = {
      dbtype = "pgsql";
      dbuser = "nextcloud";
      dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
      dbname = "nextcloud";
      adminpassFile = "/path/to/admin-pass-file";
      adminuser = "root";
    };
    };

  services.postgresql = {
    enable = true;
    ensureDatabases = [ "nextcloud" ];
    ensureUsers = [
     { name = "nextcloud";
       ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
     }
    ];
  };

  # ensure that postgres is running *before* running the setup
  systemd.services."nextcloud-setup" = {
    requires = ["postgresql.service"];
    after = ["postgresql.service"];
  };

  networking.firewall.allowedTCPPorts = [ 80 443 ];
+41 −22
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ let

  inherit (config.system) stateVersion;

  mysqlLocal = cfg.database.createLocally && cfg.config.dbtype == "mysql";
  pgsqlLocal = cfg.database.createLocally && cfg.config.dbtype == "pgsql";

in {

  imports = [
@@ -314,13 +317,9 @@ in {

      createLocally = mkOption {
        type = types.bool;
        default = false;
        default = true;
        description = lib.mdDoc ''
          Create the database and database user locally. Only available for
          mysql database.
          Note that this option will use the latest version of MariaDB which
          is not officially supported by Nextcloud. As for now a workaround
          is used to also support MariaDB version >= 10.6.
          Create the database and database user locally.
        '';
      };

@@ -352,12 +351,15 @@ in {
      };
      dbhost = mkOption {
        type = types.nullOr types.str;
        default = "localhost";
        default =
          if pgsqlLocal then "/run/postgresql"
          else if mysqlLocal then "localhost:/run/mysqld/mysqld.sock"
          else "localhost";
        defaultText = "localhost";
        description = lib.mdDoc ''
          Database host.

          Note: for using Unix authentication with PostgreSQL, this should be
          set to `/run/postgresql`.
          Database host or socket path. Defaults to the correct unix socket
          instead if `services.nextcloud.database.createLocally` is true and
          `services.nextcloud.config.dbtype` is either `pgsql` or `mysql`.
        '';
      };
      dbport = mkOption {
@@ -737,8 +739,22 @@ in {
    }

    { assertions = [
      { assertion = cfg.database.createLocally -> cfg.config.dbtype == "mysql";
        message = ''services.nextcloud.config.dbtype must be set to mysql if services.nextcloud.database.createLocally is set to true.'';
      { assertion = cfg.database.createLocally -> cfg.config.dbpassFile == null;
        message = ''
          Using `services.nextcloud.database.createLocally` (that now defaults
          to true) with database password authentication is no longer
          supported.

          If you use an external database (or want to use password auth for any
          other reason), set `services.nextcloud.database.createLocally` to
          `false`. The database won't be managed for you (use `services.mysql`
          if you want to set it up).

          If you want this module to manage your nextcloud database for you,
          unset `services.nextcloud.config.dbpassFile` and
          `services.nextcloud.config.dbhost` to use socket authentication
          instead of password.
        '';
      }
    ]; }

@@ -902,6 +918,8 @@ in {
        in {
          wantedBy = [ "multi-user.target" ];
          before = [ "phpfpm-nextcloud.service" ];
          after = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service";
          requires = optional mysqlLocal "mysql.service" ++ optional pgsqlLocal "postgresql.service";
          path = [ occ ];
          script = ''
            ${optionalString (c.dbpassFile != null) ''
@@ -1007,7 +1025,7 @@ in {

      environment.systemPackages = [ occ ];

      services.mysql = lib.mkIf cfg.database.createLocally {
      services.mysql = lib.mkIf mysqlLocal {
        enable = true;
        package = lib.mkDefault pkgs.mariadb;
        ensureDatabases = [ cfg.config.dbname ];
@@ -1015,14 +1033,15 @@ in {
          name = cfg.config.dbuser;
          ensurePermissions = { "${cfg.config.dbname}.*" = "ALL PRIVILEGES"; };
        }];
        initialScript = pkgs.writeText "mysql-init" ''
          CREATE USER '${cfg.config.dbname}'@'localhost' IDENTIFIED BY '${builtins.readFile( cfg.config.dbpassFile )}';
          CREATE DATABASE IF NOT EXISTS ${cfg.config.dbname};
          GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER,
            CREATE TEMPORARY TABLES ON ${cfg.config.dbname}.* TO '${cfg.config.dbuser}'@'localhost'
            IDENTIFIED BY '${builtins.readFile( cfg.config.dbpassFile )}';
          FLUSH privileges;
        '';
      };

      services.postgresql = mkIf pgsqlLocal {
        enable = true;
        ensureDatabases = [ cfg.config.dbname ];
        ensureUsers = [{
          name = cfg.config.dbuser;
          ensurePermissions = { "DATABASE ${cfg.config.dbname}" = "ALL PRIVILEGES"; };
        }];
      };

      services.nginx.enable = mkDefault true;
+24 −19
Original line number Diff line number Diff line
import ../make-test-python.nix ({ pkgs, ...}: let
  adminpass = "hunter2";
  adminuser = "custom-admin-username";
  username = "custom_admin_username";
  # This will be used both for redis and postgresql
  pass = "hunter2";
  # Don't do this at home, use a file outside of the nix store instead
  passFile = toString (pkgs.writeText "pass-file" ''
    ${pass}
  '');
in {
  name = "nextcloud-with-declarative-redis";
  meta = with pkgs.lib.maintainers; {
@@ -22,15 +27,15 @@ in {
          redis = true;
          memcached = false;
        };
        # This test also validates that we can use an "external" database
        database.createLocally = false;
        config = {
          dbtype = "pgsql";
          dbname = "nextcloud";
          dbuser = "nextcloud";
          dbhost = "/run/postgresql";
          inherit adminuser;
          adminpassFile = toString (pkgs.writeText "admin-pass-file" ''
            ${adminpass}
          '');
          dbuser = username;
          dbpassFile = passFile;
          adminuser = username;
          adminpassFile = passFile;
        };
        secretFile = "/etc/nextcloud-secrets.json";

@@ -52,20 +57,20 @@ in {

      systemd.services.nextcloud-setup= {
        requires = ["postgresql.service"];
        after = [
          "postgresql.service"
        ];
        after = [ "postgresql.service" ];
      };

      services.postgresql = {
        enable = true;
        ensureDatabases = [ "nextcloud" ];
        ensureUsers = [
          { name = "nextcloud";
            ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
          }
        ];
      };
      systemd.services.postgresql.postStart = pkgs.lib.mkAfter ''
        password=$(cat ${passFile})
        ${config.services.postgresql.package}/bin/psql <<EOF
          CREATE ROLE ${username} WITH LOGIN PASSWORD '$password' CREATEDB;
          CREATE DATABASE nextcloud;
          GRANT ALL PRIVILEGES ON DATABASE nextcloud TO ${username};
        EOF
      '';

      # This file is meant to contain secret options which should
      # not go into the nix store. Here it is just used to set the
@@ -86,8 +91,8 @@ in {
      export RCLONE_CONFIG_NEXTCLOUD_TYPE=webdav
      export RCLONE_CONFIG_NEXTCLOUD_URL="http://nextcloud/remote.php/webdav/"
      export RCLONE_CONFIG_NEXTCLOUD_VENDOR="nextcloud"
      export RCLONE_CONFIG_NEXTCLOUD_USER="${adminuser}"
      export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${adminpass})"
      export RCLONE_CONFIG_NEXTCLOUD_USER="${username}"
      export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${pass})"
      "''${@}"
    '';
    copySharedFile = pkgs.writeScript "copy-shared-file" ''
+0 −11
Original line number Diff line number Diff line
@@ -26,24 +26,13 @@ in {
          redis = false;
          memcached = true;
        };
        database.createLocally = true;
        config = {
          dbtype = "mysql";
          dbname = "nextcloud";
          dbuser = "nextcloud";
          dbhost = "127.0.0.1";
          dbport = 3306;
          dbpassFile = "${pkgs.writeText "dbpass" "hunter2" }";
          # Don't inherit adminuser since "root" is supposed to be the default
          adminpassFile = "${pkgs.writeText "adminpass" adminpass}"; # Don't try this at home!
        };
      };

      systemd.services.nextcloud-setup= {
        requires = ["mysql.service"];
        after = ["mysql.service"];
      };

      services.memcached.enable = true;
    };
  };
Loading