···6 cfg = config.services.nextcloud;
7 fpm = config.services.phpfpm.pools.nextcloud;
89+ inherit (cfg) datadir;
10+11 phpPackage = cfg.phpPackage.buildEnv {
12 extensions = { enabled, all }:
13 (with all;
···42 if [[ "$USER" != nextcloud ]]; then
43 sudo='exec /run/wrappers/bin/sudo -u nextcloud --preserve-env=NEXTCLOUD_CONFIG_DIR --preserve-env=OC_PASS'
44 fi
45+ export NEXTCLOUD_CONFIG_DIR="${datadir}/config"
46 $sudo \
47 ${phpPackage}/bin/php \
48 occ "$@"
···86 type = types.str;
87 default = "/var/lib/nextcloud";
88 description = "Storage path of nextcloud.";
89+ };
90+ datadir = mkOption {
91+ type = types.str;
92+ defaultText = "config.services.nextcloud.home";
93+ description = ''
94+ Data storage path of nextcloud. Will be <xref linkend="opt-services.nextcloud.home" /> by default.
95+ This folder will be populated with a config.php and data folder which contains the state of the instance (excl the database).";
96+ '';
97+ example = "/mnt/nextcloud-file";
98+ };
99+ extraApps = mkOption {
100+ type = types.attrsOf types.package;
101+ default = { };
102+ description = ''
103+ Extra apps to install. Should be an attrSet of appid to packages generated by fetchNextcloudApp.
104+ The appid must be identical to the "id" value in the apps appinfo/info.xml.
105+ Using this will disable the appstore to prevent Nextcloud from updating these apps (see <xref linkend="opt-services.nextcloud.appstoreEnable" />).
106+ '';
107+ example = literalExpression ''
108+ {
109+ maps = pkgs.fetchNextcloudApp {
110+ name = "maps";
111+ sha256 = "007y80idqg6b6zk6kjxg4vgw0z8fsxs9lajnv49vv1zjy6jx2i1i";
112+ url = "https://github.com/nextcloud/maps/releases/download/v0.1.9/maps-0.1.9.tar.gz";
113+ version = "0.1.9";
114+ };
115+ phonetrack = pkgs.fetchNextcloudApp {
116+ name = "phonetrack";
117+ sha256 = "0qf366vbahyl27p9mshfma1as4nvql6w75zy2zk5xwwbp343vsbc";
118+ url = "https://gitlab.com/eneiluj/phonetrack-oc/-/wikis/uploads/931aaaf8dca24bf31a7e169a83c17235/phonetrack-0.6.9.tar.gz";
119+ version = "0.6.9";
120+ };
121+ }
122+ '';
123+ };
124+ extraAppsEnable = mkOption {
125+ type = types.bool;
126+ default = true;
127+ description = ''
128+ Automatically enable the apps in <xref linkend="opt-services.nextcloud.extraApps" /> every time nextcloud starts.
129+ If set to false, apps need to be enabled in the Nextcloud user interface or with nextcloud-occ app:enable.
130+ '';
131+ };
132+ appstoreEnable = mkOption {
133+ type = types.nullOr types.bool;
134+ default = null;
135+ example = true;
136+ description = ''
137+ Allow the installation of apps and app updates from the store.
138+ Enabled by default unless there are packages in <xref linkend="opt-services.nextcloud.extraApps" />.
139+ Set to true to force enable the store even if <xref linkend="opt-services.nextcloud.extraApps" /> is used.
140+ Set to false to disable the installation of apps from the global appstore. App management is always enabled regardless of this setting.
141+ '';
142 };
143 logLevel = mkOption {
144 type = types.ints.between 0 4;
···579 else nextcloud22
580 );
581582+ services.nextcloud.datadir = mkOptionDefault config.services.nextcloud.home;
583+584 services.nextcloud.phpPackage =
585 if versionOlder cfg.package.version "21" then pkgs.php74
586 else pkgs.php80;
···620 ]
621 '';
622623+ showAppStoreSetting = cfg.appstoreEnable != null || cfg.extraApps != {};
624+ renderedAppStoreSetting =
625+ let
626+ x = cfg.appstoreEnable;
627+ in
628+ if x == null then "false"
629+ else boolToString x;
630+631 overrideConfig = pkgs.writeText "nextcloud-config.php" ''
632 <?php
633 ${optionalString requiresReadSecretFunction ''
···646 ''}
647 $CONFIG = [
648 'apps_paths' => [
649+ ${optionalString (cfg.extraApps != { }) "[ 'path' => '${cfg.home}/nix-apps', 'url' => '/nix-apps', 'writable' => false ],"}
650 [ 'path' => '${cfg.home}/apps', 'url' => '/apps', 'writable' => false ],
651 [ 'path' => '${cfg.home}/store-apps', 'url' => '/store-apps', 'writable' => true ],
652 ],
653+ ${optionalString (showAppStoreSetting) "'appstoreenabled' => ${renderedAppStoreSetting},"}
654+ 'datadirectory' => '${datadir}/data',
655 'skeletondirectory' => '${cfg.skeletonDirectory}',
656 ${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"}
657 'log_type' => 'syslog',
···695 "--database-pass" = "\$${dbpass.arg}";
696 "--admin-user" = ''"${c.adminuser}"'';
697 "--admin-pass" = "\$${adminpass.arg}";
698+ "--data-dir" = ''"${datadir}/data"'';
699 });
700 in ''
701 ${mkExport dbpass}
···737738 ln -sf ${cfg.package}/apps ${cfg.home}/
739740+ # Install extra apps
741+ ln -sfT \
742+ ${pkgs.linkFarm "nix-apps"
743+ (mapAttrsToList (name: path: { inherit name path; }) cfg.extraApps)} \
744+ ${cfg.home}/nix-apps
745+746 # create nextcloud directories.
747 # if the directories exist already with wrong permissions, we fix that
748+ for dir in ${datadir}/config ${datadir}/data ${cfg.home}/store-apps ${cfg.home}/nix-apps; do
749 if [ ! -e $dir ]; then
750 install -o nextcloud -g nextcloud -d $dir
751 elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then
···753 fi
754 done
755756+ ln -sf ${overrideConfig} ${datadir}/config/override.config.php
757758 # Do not install if already installed
759+ if [[ ! -e ${datadir}/config/config.php ]]; then
760 ${occInstallCmd}
761 fi
762763 ${occ}/bin/nextcloud-occ upgrade
764765 ${occ}/bin/nextcloud-occ config:system:delete trusted_domains
766+767+ ${optionalString (cfg.extraAppsEnable && cfg.extraApps != { }) ''
768+ # Try to enable apps (don't fail when one of them cannot be enabled , eg. due to incompatible version)
769+ ${occ}/bin/nextcloud-occ app:enable ${concatStringsSep " " (attrNames cfg.extraApps)}
770+ ''}
771+772 ${occSetTrustedDomainsCmd}
773 '';
774 serviceConfig.Type = "oneshot";
775 serviceConfig.User = "nextcloud";
776 };
777 nextcloud-cron = {
778+ environment.NEXTCLOUD_CONFIG_DIR = "${datadir}/config";
779 serviceConfig.Type = "oneshot";
780 serviceConfig.User = "nextcloud";
781 serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${cfg.package}/cron.php";
···794 group = "nextcloud";
795 phpPackage = phpPackage;
796 phpEnv = {
797+ NEXTCLOUD_CONFIG_DIR = "${datadir}/config";
798 PATH = "/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin";
799 };
800 settings = mapAttrs (name: mkDefault) {
···841 extraConfig = "rewrite ^ /index.php;";
842 };
843 "~ ^/store-apps" = {
844+ priority = 201;
845+ extraConfig = "root ${cfg.home};";
846+ };
847+ "~ ^/nix-apps" = {
848 priority = 201;
849 extraConfig = "root ${cfg.home};";
850 };
+6
nixos/modules/services/web-apps/nextcloud.xml
···237 Some apps may require extra PHP extensions to be installed.
238 This can be configured with the <xref linkend="opt-services.nextcloud.phpExtraExtensions" /> setting.
239 </para>
000000240 </section>
241242 <section xml:id="module-services-nextcloud-maintainer-info">
···237 Some apps may require extra PHP extensions to be installed.
238 This can be configured with the <xref linkend="opt-services.nextcloud.phpExtraExtensions" /> setting.
239 </para>
240+241+ <para>
242+ Alternatively, extra apps can also be declared with the <xref linkend="opt-services.nextcloud.extraApps" /> setting.
243+ When using this setting, apps can no longer be managed statefully because this can lead to Nextcloud updating apps
244+ that are managed by Nix. If you want automatic updates it is recommended that you use web interface to install apps.
245+ </para>
246 </section>
247248 <section xml:id="module-services-nextcloud-maintainer-info">
+6
nixos/tests/nextcloud/basic.nix
···33 in {
34 networking.firewall.allowedTCPPorts = [ 80 ];
35000036 services.nextcloud = {
37 enable = true;
038 hostName = "nextcloud";
39 config = {
40 # Don't inherit adminuser since "root" is supposed to be the default
···98 "${withRcloneEnv} ${copySharedFile}"
99 )
100 client.wait_for_unit("multi-user.target")
0101 client.succeed(
102 "${withRcloneEnv} ${diffSharedFile}"
103 )
···520 tests = callPackages ../build-support/fetchfirefoxaddon/tests.nix { };
521 };
52200523 # `fetchurl' downloads a file from the network.
524 fetchurl = if stdenv.buildPlatform != stdenv.hostPlatform
525 then buildPackages.fetchurl # No need to do special overrides twice,
···520 tests = callPackages ../build-support/fetchfirefoxaddon/tests.nix { };
521 };
522523+ fetchNextcloudApp = callPackage ../build-support/fetchnextcloudapp {};
524+525 # `fetchurl' downloads a file from the network.
526 fetchurl = if stdenv.buildPlatform != stdenv.hostPlatform
527 then buildPackages.fetchurl # No need to do special overrides twice,