diff options
Diffstat (limited to 'nixos/modules/services/web-apps/nextcloud.nix')
-rw-r--r-- | nixos/modules/services/web-apps/nextcloud.nix | 210 |
1 files changed, 147 insertions, 63 deletions
diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix index 7da119758fc..5e15aaba096 100644 --- a/nixos/modules/services/web-apps/nextcloud.nix +++ b/nixos/modules/services/web-apps/nextcloud.nix @@ -6,17 +6,19 @@ let cfg = config.services.nextcloud; fpm = config.services.phpfpm.pools.nextcloud; - phpPackage = - let - base = pkgs.php74; - in - base.buildEnv { - extensions = { enabled, all }: with all; - enabled ++ [ - apcu redis memcached imagick - ]; - extraConfig = phpOptionsStr; - }; + phpPackage = pkgs.php74.buildEnv { + extensions = { enabled, all }: + (with all; + enabled + ++ optional cfg.enableImagemagick imagick + # Optionally enabled depending on caching settings + ++ optional cfg.caching.apcu apcu + ++ optional cfg.caching.redis redis + ++ optional cfg.caching.memcached memcached + ) + ++ cfg.phpExtraExtensions all; # Enabled by user + extraConfig = toKeyValue phpOptions; + }; toKeyValue = generators.toKeyValue { mkKeyValue = generators.mkKeyValueDefault {} " = "; @@ -26,8 +28,10 @@ let upload_max_filesize = cfg.maxUploadSize; post_max_size = cfg.maxUploadSize; memory_limit = cfg.maxUploadSize; - } // cfg.phpOptions; - phpOptionsStr = toKeyValue phpOptions; + } // cfg.phpOptions + // optionalAttrs cfg.caching.apcu { + "apc.enable_cli" = "1"; + }; occ = pkgs.writeScriptBin "nextcloud-occ" '' #! ${pkgs.runtimeShell} @@ -39,7 +43,7 @@ let export NEXTCLOUD_CONFIG_DIR="${cfg.home}/config" $sudo \ ${phpPackage}/bin/php \ - occ $* + occ "$@" ''; inherit (config.system) stateVersion; @@ -59,6 +63,9 @@ in { 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`). '') + (mkRemovedOptionModule [ "services" "nextcloud" "disableImagemagick" ] '' + Use services.nextcloud.nginx.enableImagemagick instead. + '') ]; options.services.nextcloud = { @@ -85,7 +92,7 @@ in { package = mkOption { type = types.package; description = "Which package to use for the Nextcloud instance."; - relatedPackages = [ "nextcloud17" "nextcloud18" "nextcloud19" ]; + relatedPackages = [ "nextcloud20" "nextcloud21" "nextcloud22" ]; }; maxUploadSize = mkOption { @@ -116,6 +123,21 @@ in { ''; }; + phpExtraExtensions = mkOption { + type = with types; functionTo (listOf package); + default = all: []; + defaultText = "all: []"; + description = '' + Additional PHP extensions to use for nextcloud. + By default, only extensions necessary for a vanilla nextcloud installation are enabled, + but you may choose from the list of available extensions and add further ones. + This is sometimes necessary to be able to install a certain nextcloud app that has additional requirements. + ''; + example = literalExample '' + all: [ all.pdlib all.bz2 ] + ''; + }; + phpOptions = mkOption { type = types.attrsOf types.str; default = { @@ -228,7 +250,8 @@ in { type = types.nullOr types.str; default = null; description = '' - The full path to a file that contains the admin's password. + The full path to a file that contains the admin's password. Must be + readable by user <literal>nextcloud</literal>. ''; }; @@ -263,6 +286,34 @@ in { may be served via HTTPS. ''; }; + + defaultPhoneRegion = mkOption { + default = null; + type = types.nullOr types.str; + example = "DE"; + description = '' + <warning> + <para>This option exists since Nextcloud 21! If older versions are used, + this will throw an eval-error!</para> + </warning> + + <link xlink:href="https://www.iso.org/iso-3166-country-codes.html">ISO 3611-1</link> + country codes for automatic phone-number detection without a country code. + + With e.g. <literal>DE</literal> set, the <literal>+49</literal> can be omitted for + phone-numbers. + ''; + }; + }; + + enableImagemagick = mkEnableOption '' + Whether to load the ImageMagick module into PHP. + This is used by the theming app and for generating previews of certain images (e.g. SVG and HEIF). + You may want to disable it for increased security. In that case, previews will still be available + for some images (e.g. JPEG and PNG). + See https://github.com/nextcloud/server/issues/13099 + '' // { + default = true; }; caching = { @@ -328,39 +379,33 @@ in { && !(acfg.adminpass != null && acfg.adminpassFile != null)); message = "Please specify exactly one of adminpass or adminpassFile"; } + { assertion = versionOlder cfg.package.version "21" -> cfg.config.defaultPhoneRegion == null; + message = "The `defaultPhoneRegion'-setting is only supported for Nextcloud >=21!"; + } ]; - warnings = [] - ++ (optional (cfg.poolConfig != null) '' - Using config.services.nextcloud.poolConfig is deprecated and will become unsupported in a future release. - Please migrate your configuration to config.services.nextcloud.poolSettings. - '') - ++ (optional (versionOlder cfg.package.version "18") '' - A legacy Nextcloud install (from before NixOS 20.03) may be installed. + warnings = let + latest = 22; + upgradeWarning = major: nixos: + '' + A legacy Nextcloud install (from before NixOS ${nixos}) may be installed. - You're currently deploying an older version of Nextcloud. This may be needed - since Nextcloud doesn't allow major version upgrades that skip multiple - versions (i.e. an upgrade from 16 is possible to 17, but not 16 to 18). + After nextcloud${toString major} is installed successfully, you can safely upgrade + to ${toString (major + 1)}. The latest version available is nextcloud${toString latest}. - It is assumed that Nextcloud will be upgraded from version 16 to 17. + Please note that Nextcloud doesn't support upgrades across multiple major versions + (i.e. an upgrade from 16 is possible to 17, but not 16 to 18). - * If this is a fresh install, there will be no upgrade to do now. - - * If this server already had Nextcloud installed, first deploy this to your - server, and wait until the upgrade to 17 is finished. - - Then, set `services.nextcloud.package` to `pkgs.nextcloud18` to upgrade to - Nextcloud version 18. Please note that Nextcloud 19 is already out and it's - recommended to upgrade to nextcloud19 after that. + The package can be upgraded by explicitly declaring the service-option + `services.nextcloud.package`. + ''; + in (optional (cfg.poolConfig != null) '' + Using config.services.nextcloud.poolConfig is deprecated and will become unsupported in a future release. + Please migrate your configuration to config.services.nextcloud.poolSettings. '') - ++ (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). - ''); + ++ (optional (versionOlder cfg.package.version "20") (upgradeWarning 19 "21.05")) + ++ (optional (versionOlder cfg.package.version "21") (upgradeWarning 20 "21.05")) + ++ (optional (versionOlder cfg.package.version "22") (upgradeWarning 21 "21.11")); services.nextcloud.package = with pkgs; mkDefault ( @@ -370,9 +415,13 @@ in { nextcloud defined in an overlay, please set `services.nextcloud.package` to `pkgs.nextcloud`. '' - else if versionOlder stateVersion "20.03" then nextcloud17 - else if versionOlder stateVersion "20.09" then nextcloud18 - else nextcloud19 + # 21.03 will not be an official release - it was instead 21.05. + # This versionOlder statement remains set to 21.03 for backwards compatibility. + # See https://github.com/NixOS/nixpkgs/pull/108899 and + # https://github.com/NixOS/rfcs/blob/master/rfcs/0080-nixos-release-schedule.md. + else if versionOlder stateVersion "21.03" then nextcloud19 + else if versionOlder stateVersion "21.11" then nextcloud21 + else nextcloud22 ); } @@ -399,7 +448,9 @@ in { $file = "${c.dbpassFile}"; if (!file_exists($file)) { throw new \RuntimeException(sprintf( - "Cannot start Nextcloud, dbpass file %s set by NixOS doesn't exist!", + "Cannot start Nextcloud, dbpass file %s set by NixOS doesn't seem to " + . "exist! Please make sure that the file exists and has appropriate " + . "permissions for user & group 'nextcloud'!", $file )); } @@ -428,6 +479,7 @@ in { 'dbtype' => '${c.dbtype}', 'trusted_domains' => ${writePhpArrary ([ cfg.hostName ] ++ c.extraTrustedDomains)}, 'trusted_proxies' => ${writePhpArrary (c.trustedProxies)}, + ${optionalString (c.defaultPhoneRegion != null) "'default_phone_region' => '${c.defaultPhoneRegion}',"} ]; ''; occInstallCmd = let @@ -435,7 +487,7 @@ in { then ''"$(<"${toString c.dbpassFile}")"'' else if c.dbpass != null then ''"${toString c.dbpass}"'' - else null; + else ''""''; adminpass = if c.adminpassFile != null then ''"$(<"${toString c.adminpassFile}")"'' else ''"${toString c.adminpass}"''; @@ -449,8 +501,7 @@ in { ${if c.dbhost != null then "--database-host" else null} = ''"${c.dbhost}"''; ${if c.dbport != null then "--database-port" else null} = ''"${toString c.dbport}"''; ${if c.dbuser != null then "--database-user" else null} = ''"${c.dbuser}"''; - ${if (any (x: x != null) [c.dbpass c.dbpassFile]) - then "--database-pass" else null} = dbpass; + "--database-pass" = dbpass; ${if c.dbtableprefix != null then "--database-table-prefix" else null} = ''"${toString c.dbtableprefix}"''; "--admin-user" = ''"${c.adminuser}"''; @@ -473,6 +524,28 @@ in { path = [ occ ]; script = '' chmod og+x ${cfg.home} + + ${optionalString (c.dbpassFile != null) '' + if [ ! -r "${c.dbpassFile}" ]; then + echo "dbpassFile ${c.dbpassFile} is not readable by nextcloud:nextcloud! Aborting..." + exit 1 + fi + if [ -z "$(<${c.dbpassFile})" ]; then + echo "dbpassFile ${c.dbpassFile} is empty!" + exit 1 + fi + ''} + ${optionalString (c.adminpassFile != null) '' + if [ ! -r "${c.adminpassFile}" ]; then + echo "adminpassFile ${c.adminpassFile} is not readable by nextcloud:nextcloud! Aborting..." + exit 1 + fi + if [ -z "$(<${c.adminpassFile})" ]; then + echo "adminpassFile ${c.adminpassFile} is empty!" + exit 1 + fi + ''} + ln -sf ${cfg.package}/apps ${cfg.home}/ # create nextcloud directories. @@ -518,7 +591,6 @@ in { pools.nextcloud = { user = "nextcloud"; group = "nextcloud"; - phpOptions = phpOptionsStr; phpPackage = phpPackage; phpEnv = { NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config"; @@ -536,12 +608,14 @@ in { home = "${cfg.home}"; group = "nextcloud"; createHome = true; + isSystemUser = true; }; users.groups.nextcloud.members = [ "nextcloud" config.services.nginx.user ]; environment.systemPackages = [ occ ]; services.nginx.enable = mkDefault true; + services.nginx.virtualHosts.${cfg.hostName} = { root = cfg.package; locations = { @@ -553,9 +627,17 @@ in { access_log off; ''; }; + "= /" = { + priority = 100; + extraConfig = '' + if ( $http_user_agent ~ ^DavClnt ) { + return 302 /remote.php/webdav/$is_args$args; + } + ''; + }; "/" = { priority = 900; - extraConfig = "try_files $uri $uri/ /index.php$request_uri;"; + extraConfig = "rewrite ^ /index.php;"; }; "~ ^/store-apps" = { priority = 201; @@ -564,11 +646,15 @@ in { "^~ /.well-known" = { priority = 210; extraConfig = '' + absolute_redirect off; location = /.well-known/carddav { - return 301 $scheme://$host/remote.php/dav; + return 301 /remote.php/dav; } location = /.well-known/caldav { - return 301 $scheme://$host/remote.php/dav; + return 301 /remote.php/dav; + } + location ~ ^/\.well-known/(?!acme-challenge|pki-validation) { + return 301 /index.php$request_uri; } try_files $uri $uri/ =404; ''; @@ -576,10 +662,10 @@ in { "~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)".extraConfig = '' return 404; ''; - "~ ^/(?:\\.|autotest|occ|issue|indie|db_|console)".extraConfig = '' + "~ ^/(?:\\.(?!well-known)|autotest|occ|issue|indie|db_|console)".extraConfig = '' return 404; ''; - "~ \\.php(?:$|/)" = { + "~ ^\\/(?:index|remote|public|cron|core\\/ajax\\/update|status|ocs\\/v[12]|updater\\/.+|oc[ms]-provider\\/.+|.+\\/richdocumentscode\\/proxy)\\.php(?:$|\\/)" = { priority = 500; extraConfig = '' include ${config.services.nginx.package}/conf/fastcgi.conf; @@ -597,24 +683,22 @@ in { fastcgi_read_timeout 120s; ''; }; - "~ \\.(?:css|js|svg|gif|map)$".extraConfig = '' + "~ \\.(?:css|js|woff2?|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; ''; + "~ \\.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$".extraConfig = '' + try_files $uri /index.php$request_uri; + access_log off; + ''; }; 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; |