diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix
index 4d7f16b1e1a9..62ae763b69bc 100644
--- a/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixos/modules/services/web-apps/nextcloud.nix
@@ -6,6 +6,8 @@ let
cfg = config.services.nextcloud;
fpm = config.services.phpfpm.pools.nextcloud;
+ inherit (cfg) datadir;
+
phpPackage = cfg.phpPackage.buildEnv {
extensions = { enabled, all }:
(with all;
@@ -40,7 +42,7 @@ let
if [[ "$USER" != nextcloud ]]; then
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"
+ export NEXTCLOUD_CONFIG_DIR="${datadir}/config"
$sudo \
${phpPackage}/bin/php \
occ "$@"
@@ -85,6 +87,59 @@ in {
default = "/var/lib/nextcloud";
description = "Storage path of nextcloud.";
};
+ datadir = mkOption {
+ type = types.str;
+ defaultText = "config.services.nextcloud.home";
+ description = ''
+ Data storage path of nextcloud. Will be by default.
+ This folder will be populated with a config.php and data folder which contains the state of the instance (excl the database).";
+ '';
+ example = "/mnt/nextcloud-file";
+ };
+ extraApps = mkOption {
+ type = types.attrsOf types.package;
+ default = { };
+ description = ''
+ Extra apps to install. Should be an attrSet of appid to packages generated by fetchNextcloudApp.
+ The appid must be identical to the "id" value in the apps appinfo/info.xml.
+ Using this will disable the appstore to prevent Nextcloud from updating these apps (see ).
+ '';
+ example = literalExpression ''
+ {
+ maps = pkgs.fetchNextcloudApp {
+ name = "maps";
+ sha256 = "007y80idqg6b6zk6kjxg4vgw0z8fsxs9lajnv49vv1zjy6jx2i1i";
+ url = "https://github.com/nextcloud/maps/releases/download/v0.1.9/maps-0.1.9.tar.gz";
+ version = "0.1.9";
+ };
+ phonetrack = pkgs.fetchNextcloudApp {
+ name = "phonetrack";
+ sha256 = "0qf366vbahyl27p9mshfma1as4nvql6w75zy2zk5xwwbp343vsbc";
+ url = "https://gitlab.com/eneiluj/phonetrack-oc/-/wikis/uploads/931aaaf8dca24bf31a7e169a83c17235/phonetrack-0.6.9.tar.gz";
+ version = "0.6.9";
+ };
+ }
+ '';
+ };
+ extraAppsEnable = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Automatically enable the apps in every time nextcloud starts.
+ If set to false, apps need to be enabled in the Nextcloud user interface or with nextcloud-occ app:enable.
+ '';
+ };
+ appstoreEnable = mkOption {
+ type = types.nullOr types.bool;
+ default = null;
+ example = true;
+ description = ''
+ Allow the installation of apps and app updates from the store.
+ Enabled by default unless there are packages in .
+ Set to true to force enable the store even if is used.
+ Set to false to disable the installation of apps from the global appstore. App management is always enabled regardless of this setting.
+ '';
+ };
logLevel = mkOption {
type = types.ints.between 0 4;
default = 2;
@@ -524,6 +579,8 @@ in {
else nextcloud22
);
+ services.nextcloud.datadir = mkOptionDefault config.services.nextcloud.home;
+
services.nextcloud.phpPackage =
if versionOlder cfg.package.version "21" then pkgs.php74
else pkgs.php80;
@@ -563,6 +620,14 @@ in {
]
'';
+ showAppStoreSetting = cfg.appstoreEnable != null || cfg.extraApps != {};
+ renderedAppStoreSetting =
+ let
+ x = cfg.appstoreEnable;
+ in
+ if x == null then "false"
+ else boolToString x;
+
overrideConfig = pkgs.writeText "nextcloud-config.php" ''
[
+ ${optionalString (cfg.extraApps != { }) "[ 'path' => '${cfg.home}/nix-apps', 'url' => '/nix-apps', 'writable' => false ],"}
[ 'path' => '${cfg.home}/apps', 'url' => '/apps', 'writable' => false ],
[ 'path' => '${cfg.home}/store-apps', 'url' => '/store-apps', 'writable' => true ],
],
- 'datadirectory' => '${cfg.home}/data',
+ ${optionalString (showAppStoreSetting) "'appstoreenabled' => ${renderedAppStoreSetting},"}
+ 'datadirectory' => '${datadir}/data',
'skeletondirectory' => '${cfg.skeletonDirectory}',
${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"}
'log_type' => 'syslog',
@@ -628,7 +695,7 @@ in {
"--database-pass" = "\$${dbpass.arg}";
"--admin-user" = ''"${c.adminuser}"'';
"--admin-pass" = "\$${adminpass.arg}";
- "--data-dir" = ''"${cfg.home}/data"'';
+ "--data-dir" = ''"${datadir}/data"'';
});
in ''
${mkExport dbpass}
@@ -670,9 +737,15 @@ in {
ln -sf ${cfg.package}/apps ${cfg.home}/
+ # Install extra apps
+ ln -sfT \
+ ${pkgs.linkFarm "nix-apps"
+ (mapAttrsToList (name: path: { inherit name path; }) cfg.extraApps)} \
+ ${cfg.home}/nix-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
+ for dir in ${datadir}/config ${datadir}/data ${cfg.home}/store-apps ${cfg.home}/nix-apps; do
if [ ! -e $dir ]; then
install -o nextcloud -g nextcloud -d $dir
elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then
@@ -680,23 +753,29 @@ in {
fi
done
- ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php
+ ln -sf ${overrideConfig} ${datadir}/config/override.config.php
# Do not install if already installed
- if [[ ! -e ${cfg.home}/config/config.php ]]; then
+ if [[ ! -e ${datadir}/config/config.php ]]; then
${occInstallCmd}
fi
${occ}/bin/nextcloud-occ upgrade
${occ}/bin/nextcloud-occ config:system:delete trusted_domains
+
+ ${optionalString (cfg.extraAppsEnable && cfg.extraApps != { }) ''
+ # Try to enable apps (don't fail when one of them cannot be enabled , eg. due to incompatible version)
+ ${occ}/bin/nextcloud-occ app:enable ${concatStringsSep " " (attrNames cfg.extraApps)}
+ ''}
+
${occSetTrustedDomainsCmd}
'';
serviceConfig.Type = "oneshot";
serviceConfig.User = "nextcloud";
};
nextcloud-cron = {
- environment.NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
+ environment.NEXTCLOUD_CONFIG_DIR = "${datadir}/config";
serviceConfig.Type = "oneshot";
serviceConfig.User = "nextcloud";
serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${cfg.package}/cron.php";
@@ -715,7 +794,7 @@ in {
group = "nextcloud";
phpPackage = phpPackage;
phpEnv = {
- NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
+ NEXTCLOUD_CONFIG_DIR = "${datadir}/config";
PATH = "/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin";
};
settings = mapAttrs (name: mkDefault) {
@@ -765,6 +844,10 @@ in {
priority = 201;
extraConfig = "root ${cfg.home};";
};
+ "~ ^/nix-apps" = {
+ priority = 201;
+ extraConfig = "root ${cfg.home};";
+ };
"^~ /.well-known" = {
priority = 210;
extraConfig = ''
diff --git a/nixos/modules/services/web-apps/nextcloud.xml b/nixos/modules/services/web-apps/nextcloud.xml
index ed84487d233a..9d9cb8dfb3f2 100644
--- a/nixos/modules/services/web-apps/nextcloud.xml
+++ b/nixos/modules/services/web-apps/nextcloud.xml
@@ -237,6 +237,12 @@
Some apps may require extra PHP extensions to be installed.
This can be configured with the setting.
+
+
+ Alternatively, extra apps can also be declared with the setting.
+ When using this setting, apps can no longer be managed statefully because this can lead to Nextcloud updating apps
+ that are managed by Nix. If you want automatic updates it is recommended that you use web interface to install apps.
+
diff --git a/nixos/tests/nextcloud/basic.nix b/nixos/tests/nextcloud/basic.nix
index 1a7b25d5a49e..eb37470a4c7b 100644
--- a/nixos/tests/nextcloud/basic.nix
+++ b/nixos/tests/nextcloud/basic.nix
@@ -33,8 +33,13 @@ in {
in {
networking.firewall.allowedTCPPorts = [ 80 ];
+ systemd.tmpfiles.rules = [
+ "d /var/lib/nextcloud-data 0750 nextcloud nginx - -"
+ ];
+
services.nextcloud = {
enable = true;
+ datadir = "/var/lib/nextcloud-data";
hostName = "nextcloud";
config = {
# Don't inherit adminuser since "root" is supposed to be the default
@@ -98,6 +103,7 @@ in {
"${withRcloneEnv} ${copySharedFile}"
)
client.wait_for_unit("multi-user.target")
+ nextcloud.succeed("test -f /var/lib/nextcloud-data/data/root/files/test-shared-file")
client.succeed(
"${withRcloneEnv} ${diffSharedFile}"
)
diff --git a/pkgs/build-support/fetchnextcloudapp/default.nix b/pkgs/build-support/fetchnextcloudapp/default.nix
new file mode 100644
index 000000000000..7fe5b35e2596
--- /dev/null
+++ b/pkgs/build-support/fetchnextcloudapp/default.nix
@@ -0,0 +1,37 @@
+{ stdenv, gnutar, findutils, fetchurl, ... }:
+{ name
+, url
+, version
+, sha256
+, patches ? [ ]
+}:
+stdenv.mkDerivation {
+ name = "nc-app-${name}";
+ inherit version patches;
+
+ src = fetchurl {
+ inherit url sha256;
+ };
+
+ nativeBuildInputs = [
+ gnutar
+ findutils
+ ];
+
+ unpackPhase = ''
+ tar -xzpf $src
+ '';
+
+ installPhase = ''
+ approot="$(dirname $(dirname $(find -path '*/appinfo/info.xml' | head -n 1)))"
+
+ if [ -d "$approot" ];
+ then
+ mv "$approot/" $out
+ chmod -R a-w $out
+ else
+ echo "Could not find appinfo/info.xml"
+ exit 1;
+ fi
+ '';
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 3087a4729844..f3197712d39a 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -520,6 +520,8 @@ with pkgs;
tests = callPackages ../build-support/fetchfirefoxaddon/tests.nix { };
};
+ fetchNextcloudApp = callPackage ../build-support/fetchnextcloudapp {};
+
# `fetchurl' downloads a file from the network.
fetchurl = if stdenv.buildPlatform != stdenv.hostPlatform
then buildPackages.fetchurl # No need to do special overrides twice,