at 21.11-pre 28 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.nextcloud; 7 fpm = config.services.phpfpm.pools.nextcloud; 8 9 phpPackage = pkgs.php74.buildEnv { 10 extensions = { enabled, all }: 11 (with all; 12 enabled 13 ++ optional cfg.enableImagemagick imagick 14 # Optionally enabled depending on caching settings 15 ++ optional cfg.caching.apcu apcu 16 ++ optional cfg.caching.redis redis 17 ++ optional cfg.caching.memcached memcached 18 ) 19 ++ cfg.phpExtraExtensions all; # Enabled by user 20 extraConfig = toKeyValue phpOptions; 21 }; 22 23 toKeyValue = generators.toKeyValue { 24 mkKeyValue = generators.mkKeyValueDefault {} " = "; 25 }; 26 27 phpOptions = { 28 upload_max_filesize = cfg.maxUploadSize; 29 post_max_size = cfg.maxUploadSize; 30 memory_limit = cfg.maxUploadSize; 31 } // cfg.phpOptions 32 // optionalAttrs cfg.caching.apcu { 33 "apc.enable_cli" = "1"; 34 }; 35 36 occ = pkgs.writeScriptBin "nextcloud-occ" '' 37 #! ${pkgs.runtimeShell} 38 cd ${cfg.package} 39 sudo=exec 40 if [[ "$USER" != nextcloud ]]; then 41 sudo='exec /run/wrappers/bin/sudo -u nextcloud --preserve-env=NEXTCLOUD_CONFIG_DIR --preserve-env=OC_PASS' 42 fi 43 export NEXTCLOUD_CONFIG_DIR="${cfg.home}/config" 44 $sudo \ 45 ${phpPackage}/bin/php \ 46 occ "$@" 47 ''; 48 49 inherit (config.system) stateVersion; 50 51in { 52 53 imports = [ 54 (mkRemovedOptionModule [ "services" "nextcloud" "nginx" "enable" ] '' 55 The nextcloud module supports `nginx` as reverse-proxy by default and doesn't 56 support other reverse-proxies officially. 57 58 However it's possible to use an alternative reverse-proxy by 59 60 * disabling nginx 61 * setting `listen.owner` & `listen.group` in the phpfpm-pool to a different value 62 63 Further details about this can be found in the `Nextcloud`-section of the NixOS-manual 64 (which can be openend e.g. by running `nixos-help`). 65 '') 66 (mkRemovedOptionModule [ "services" "nextcloud" "disableImagemagick" ] '' 67 Use services.nextcloud.nginx.enableImagemagick instead. 68 '') 69 ]; 70 71 options.services.nextcloud = { 72 enable = mkEnableOption "nextcloud"; 73 hostName = mkOption { 74 type = types.str; 75 description = "FQDN for the nextcloud instance."; 76 }; 77 home = mkOption { 78 type = types.str; 79 default = "/var/lib/nextcloud"; 80 description = "Storage path of nextcloud."; 81 }; 82 logLevel = mkOption { 83 type = types.ints.between 0 4; 84 default = 2; 85 description = "Log level value between 0 (DEBUG) and 4 (FATAL)."; 86 }; 87 https = mkOption { 88 type = types.bool; 89 default = false; 90 description = "Use https for generated links."; 91 }; 92 package = mkOption { 93 type = types.package; 94 description = "Which package to use for the Nextcloud instance."; 95 relatedPackages = [ "nextcloud19" "nextcloud20" "nextcloud21" ]; 96 }; 97 98 maxUploadSize = mkOption { 99 default = "512M"; 100 type = types.str; 101 description = '' 102 Defines the upload limit for files. This changes the relevant options 103 in php.ini and nginx if enabled. 104 ''; 105 }; 106 107 skeletonDirectory = mkOption { 108 default = ""; 109 type = types.str; 110 description = '' 111 The directory where the skeleton files are located. These files will be 112 copied to the data directory of new users. Leave empty to not copy any 113 skeleton files. 114 ''; 115 }; 116 117 webfinger = mkOption { 118 type = types.bool; 119 default = false; 120 description = '' 121 Enable this option if you plan on using the webfinger plugin. 122 The appropriate nginx rewrite rules will be added to your configuration. 123 ''; 124 }; 125 126 phpExtraExtensions = mkOption { 127 type = with types; functionTo (listOf package); 128 default = all: []; 129 defaultText = "all: []"; 130 description = '' 131 Additional PHP extensions to use for nextcloud. 132 By default, only extensions necessary for a vanilla nextcloud installation are enabled, 133 but you may choose from the list of available extensions and add further ones. 134 This is sometimes necessary to be able to install a certain nextcloud app that has additional requirements. 135 ''; 136 example = literalExample '' 137 all: [ all.pdlib all.bz2 ] 138 ''; 139 }; 140 141 phpOptions = mkOption { 142 type = types.attrsOf types.str; 143 default = { 144 short_open_tag = "Off"; 145 expose_php = "Off"; 146 error_reporting = "E_ALL & ~E_DEPRECATED & ~E_STRICT"; 147 display_errors = "stderr"; 148 "opcache.enable_cli" = "1"; 149 "opcache.interned_strings_buffer" = "8"; 150 "opcache.max_accelerated_files" = "10000"; 151 "opcache.memory_consumption" = "128"; 152 "opcache.revalidate_freq" = "1"; 153 "opcache.fast_shutdown" = "1"; 154 "openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt"; 155 catch_workers_output = "yes"; 156 }; 157 description = '' 158 Options for PHP's php.ini file for nextcloud. 159 ''; 160 }; 161 162 poolSettings = mkOption { 163 type = with types; attrsOf (oneOf [ str int bool ]); 164 default = { 165 "pm" = "dynamic"; 166 "pm.max_children" = "32"; 167 "pm.start_servers" = "2"; 168 "pm.min_spare_servers" = "2"; 169 "pm.max_spare_servers" = "4"; 170 "pm.max_requests" = "500"; 171 }; 172 description = '' 173 Options for nextcloud's PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives. 174 ''; 175 }; 176 177 poolConfig = mkOption { 178 type = types.nullOr types.lines; 179 default = null; 180 description = '' 181 Options for nextcloud's PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives. 182 ''; 183 }; 184 185 config = { 186 dbtype = mkOption { 187 type = types.enum [ "sqlite" "pgsql" "mysql" ]; 188 default = "sqlite"; 189 description = "Database type."; 190 }; 191 dbname = mkOption { 192 type = types.nullOr types.str; 193 default = "nextcloud"; 194 description = "Database name."; 195 }; 196 dbuser = mkOption { 197 type = types.nullOr types.str; 198 default = "nextcloud"; 199 description = "Database user."; 200 }; 201 dbpass = mkOption { 202 type = types.nullOr types.str; 203 default = null; 204 description = '' 205 Database password. Use <literal>dbpassFile</literal> to avoid this 206 being world-readable in the <literal>/nix/store</literal>. 207 ''; 208 }; 209 dbpassFile = mkOption { 210 type = types.nullOr types.str; 211 default = null; 212 description = '' 213 The full path to a file that contains the database password. 214 ''; 215 }; 216 dbhost = mkOption { 217 type = types.nullOr types.str; 218 default = "localhost"; 219 description = '' 220 Database host. 221 222 Note: for using Unix authentication with PostgreSQL, this should be 223 set to <literal>/run/postgresql</literal>. 224 ''; 225 }; 226 dbport = mkOption { 227 type = with types; nullOr (either int str); 228 default = null; 229 description = "Database port."; 230 }; 231 dbtableprefix = mkOption { 232 type = types.nullOr types.str; 233 default = null; 234 description = "Table prefix in Nextcloud database."; 235 }; 236 adminuser = mkOption { 237 type = types.str; 238 default = "root"; 239 description = "Admin username."; 240 }; 241 adminpass = mkOption { 242 type = types.nullOr types.str; 243 default = null; 244 description = '' 245 Admin password. Use <literal>adminpassFile</literal> to avoid this 246 being world-readable in the <literal>/nix/store</literal>. 247 ''; 248 }; 249 adminpassFile = mkOption { 250 type = types.nullOr types.str; 251 default = null; 252 description = '' 253 The full path to a file that contains the admin's password. Must be 254 readable by user <literal>nextcloud</literal>. 255 ''; 256 }; 257 258 extraTrustedDomains = mkOption { 259 type = types.listOf types.str; 260 default = []; 261 description = '' 262 Trusted domains, from which the nextcloud installation will be 263 acessible. You don't need to add 264 <literal>services.nextcloud.hostname</literal> here. 265 ''; 266 }; 267 268 trustedProxies = mkOption { 269 type = types.listOf types.str; 270 default = []; 271 description = '' 272 Trusted proxies, to provide if the nextcloud installation is being 273 proxied to secure against e.g. spoofing. 274 ''; 275 }; 276 277 overwriteProtocol = mkOption { 278 type = types.nullOr (types.enum [ "http" "https" ]); 279 default = null; 280 example = "https"; 281 282 description = '' 283 Force Nextcloud to always use HTTPS i.e. for link generation. Nextcloud 284 uses the currently used protocol by default, but when behind a reverse-proxy, 285 it may use <literal>http</literal> for everything although Nextcloud 286 may be served via HTTPS. 287 ''; 288 }; 289 290 defaultPhoneRegion = mkOption { 291 default = null; 292 type = types.nullOr types.str; 293 example = "DE"; 294 description = '' 295 <warning> 296 <para>This option exists since Nextcloud 21! If older versions are used, 297 this will throw an eval-error!</para> 298 </warning> 299 300 <link xlink:href="https://www.iso.org/iso-3166-country-codes.html">ISO 3611-1</link> 301 country codes for automatic phone-number detection without a country code. 302 303 With e.g. <literal>DE</literal> set, the <literal>+49</literal> can be omitted for 304 phone-numbers. 305 ''; 306 }; 307 }; 308 309 enableImagemagick = mkEnableOption '' 310 Whether to load the ImageMagick module into PHP. 311 This is used by the theming app and for generating previews of certain images (e.g. SVG and HEIF). 312 You may want to disable it for increased security. In that case, previews will still be available 313 for some images (e.g. JPEG and PNG). 314 See https://github.com/nextcloud/server/issues/13099 315 '' // { 316 default = true; 317 }; 318 319 caching = { 320 apcu = mkOption { 321 type = types.bool; 322 default = true; 323 description = '' 324 Whether to load the APCu module into PHP. 325 ''; 326 }; 327 redis = mkOption { 328 type = types.bool; 329 default = false; 330 description = '' 331 Whether to load the Redis module into PHP. 332 You still need to enable Redis in your config.php. 333 See https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html 334 ''; 335 }; 336 memcached = mkOption { 337 type = types.bool; 338 default = false; 339 description = '' 340 Whether to load the Memcached module into PHP. 341 You still need to enable Memcached in your config.php. 342 See https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html 343 ''; 344 }; 345 }; 346 autoUpdateApps = { 347 enable = mkOption { 348 type = types.bool; 349 default = false; 350 description = '' 351 Run regular auto update of all apps installed from the nextcloud app store. 352 ''; 353 }; 354 startAt = mkOption { 355 type = with types; either str (listOf str); 356 default = "05:00:00"; 357 example = "Sun 14:00:00"; 358 description = '' 359 When to run the update. See `systemd.services.&lt;name&gt;.startAt`. 360 ''; 361 }; 362 }; 363 occ = mkOption { 364 type = types.package; 365 default = occ; 366 internal = true; 367 description = '' 368 The nextcloud-occ program preconfigured to target this Nextcloud instance. 369 ''; 370 }; 371 }; 372 373 config = mkIf cfg.enable (mkMerge [ 374 { assertions = let acfg = cfg.config; in [ 375 { assertion = !(acfg.dbpass != null && acfg.dbpassFile != null); 376 message = "Please specify no more than one of dbpass or dbpassFile"; 377 } 378 { assertion = ((acfg.adminpass != null || acfg.adminpassFile != null) 379 && !(acfg.adminpass != null && acfg.adminpassFile != null)); 380 message = "Please specify exactly one of adminpass or adminpassFile"; 381 } 382 { assertion = versionOlder cfg.package.version "21" -> cfg.config.defaultPhoneRegion == null; 383 message = "The `defaultPhoneRegion'-setting is only supported for Nextcloud >=21!"; 384 } 385 ]; 386 387 warnings = let 388 latest = 21; 389 upgradeWarning = major: nixos: 390 '' 391 A legacy Nextcloud install (from before NixOS ${nixos}) may be installed. 392 393 After nextcloud${toString major} is installed successfully, you can safely upgrade 394 to ${toString (major + 1)}. The latest version available is nextcloud${toString latest}. 395 396 Please note that Nextcloud doesn't support upgrades across multiple major versions 397 (i.e. an upgrade from 16 is possible to 17, but not 16 to 18). 398 399 The package can be upgraded by explicitly declaring the service-option 400 `services.nextcloud.package`. 401 ''; 402 in (optional (cfg.poolConfig != null) '' 403 Using config.services.nextcloud.poolConfig is deprecated and will become unsupported in a future release. 404 Please migrate your configuration to config.services.nextcloud.poolSettings. 405 '') 406 ++ (optional (versionOlder cfg.package.version "19") (upgradeWarning 18 "20.09")) 407 ++ (optional (versionOlder cfg.package.version "20") (upgradeWarning 19 "21.05")) 408 ++ (optional (versionOlder cfg.package.version "21") (upgradeWarning 20 "21.05")); 409 410 services.nextcloud.package = with pkgs; 411 mkDefault ( 412 if pkgs ? nextcloud 413 then throw '' 414 The `pkgs.nextcloud`-attribute has been removed. If it's supposed to be the default 415 nextcloud defined in an overlay, please set `services.nextcloud.package` to 416 `pkgs.nextcloud`. 417 '' 418 else if versionOlder stateVersion "20.09" then nextcloud18 419 # 21.03 will not be an official release - it was instead 21.05. 420 # This versionOlder statement remains set to 21.03 for backwards compatibility. 421 # See https://github.com/NixOS/nixpkgs/pull/108899 and 422 # https://github.com/NixOS/rfcs/blob/master/rfcs/0080-nixos-release-schedule.md. 423 else if versionOlder stateVersion "21.03" then nextcloud19 424 else nextcloud21 425 ); 426 } 427 428 { systemd.timers.nextcloud-cron = { 429 wantedBy = [ "timers.target" ]; 430 timerConfig.OnBootSec = "5m"; 431 timerConfig.OnUnitActiveSec = "15m"; 432 timerConfig.Unit = "nextcloud-cron.service"; 433 }; 434 435 systemd.services = { 436 # When upgrading the Nextcloud package, Nextcloud can report errors such as 437 # "The files of the app [all apps in /var/lib/nextcloud/apps] were not replaced correctly" 438 # Restarting phpfpm on Nextcloud package update fixes these issues (but this is a workaround). 439 phpfpm-nextcloud.restartTriggers = [ cfg.package ]; 440 441 nextcloud-setup = let 442 c = cfg.config; 443 writePhpArrary = a: "[${concatMapStringsSep "," (val: ''"${toString val}"'') a}]"; 444 overrideConfig = pkgs.writeText "nextcloud-config.php" '' 445 <?php 446 ${optionalString (c.dbpassFile != null) '' 447 function nix_read_pwd() { 448 $file = "${c.dbpassFile}"; 449 if (!file_exists($file)) { 450 throw new \RuntimeException(sprintf( 451 "Cannot start Nextcloud, dbpass file %s set by NixOS doesn't seem to " 452 . "exist! Please make sure that the file exists and has appropriate " 453 . "permissions for user & group 'nextcloud'!", 454 $file 455 )); 456 } 457 458 return trim(file_get_contents($file)); 459 } 460 ''} 461 $CONFIG = [ 462 'apps_paths' => [ 463 [ 'path' => '${cfg.home}/apps', 'url' => '/apps', 'writable' => false ], 464 [ 'path' => '${cfg.home}/store-apps', 'url' => '/store-apps', 'writable' => true ], 465 ], 466 'datadirectory' => '${cfg.home}/data', 467 'skeletondirectory' => '${cfg.skeletonDirectory}', 468 ${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"} 469 'log_type' => 'syslog', 470 'log_level' => '${builtins.toString cfg.logLevel}', 471 ${optionalString (c.overwriteProtocol != null) "'overwriteprotocol' => '${c.overwriteProtocol}',"} 472 ${optionalString (c.dbname != null) "'dbname' => '${c.dbname}',"} 473 ${optionalString (c.dbhost != null) "'dbhost' => '${c.dbhost}',"} 474 ${optionalString (c.dbport != null) "'dbport' => '${toString c.dbport}',"} 475 ${optionalString (c.dbuser != null) "'dbuser' => '${c.dbuser}',"} 476 ${optionalString (c.dbtableprefix != null) "'dbtableprefix' => '${toString c.dbtableprefix}',"} 477 ${optionalString (c.dbpass != null) "'dbpassword' => '${c.dbpass}',"} 478 ${optionalString (c.dbpassFile != null) "'dbpassword' => nix_read_pwd(),"} 479 'dbtype' => '${c.dbtype}', 480 'trusted_domains' => ${writePhpArrary ([ cfg.hostName ] ++ c.extraTrustedDomains)}, 481 'trusted_proxies' => ${writePhpArrary (c.trustedProxies)}, 482 ${optionalString (c.defaultPhoneRegion != null) "'default_phone_region' => '${c.defaultPhoneRegion}',"} 483 ]; 484 ''; 485 occInstallCmd = let 486 dbpass = if c.dbpassFile != null 487 then ''"$(<"${toString c.dbpassFile}")"'' 488 else if c.dbpass != null 489 then ''"${toString c.dbpass}"'' 490 else ''""''; 491 adminpass = if c.adminpassFile != null 492 then ''"$(<"${toString c.adminpassFile}")"'' 493 else ''"${toString c.adminpass}"''; 494 installFlags = concatStringsSep " \\\n " 495 (mapAttrsToList (k: v: "${k} ${toString v}") { 496 "--database" = ''"${c.dbtype}"''; 497 # The following attributes are optional depending on the type of 498 # database. Those that evaluate to null on the left hand side 499 # will be omitted. 500 ${if c.dbname != null then "--database-name" else null} = ''"${c.dbname}"''; 501 ${if c.dbhost != null then "--database-host" else null} = ''"${c.dbhost}"''; 502 ${if c.dbport != null then "--database-port" else null} = ''"${toString c.dbport}"''; 503 ${if c.dbuser != null then "--database-user" else null} = ''"${c.dbuser}"''; 504 "--database-pass" = dbpass; 505 ${if c.dbtableprefix != null 506 then "--database-table-prefix" else null} = ''"${toString c.dbtableprefix}"''; 507 "--admin-user" = ''"${c.adminuser}"''; 508 "--admin-pass" = adminpass; 509 "--data-dir" = ''"${cfg.home}/data"''; 510 }); 511 in '' 512 ${occ}/bin/nextcloud-occ maintenance:install \ 513 ${installFlags} 514 ''; 515 occSetTrustedDomainsCmd = concatStringsSep "\n" (imap0 516 (i: v: '' 517 ${occ}/bin/nextcloud-occ config:system:set trusted_domains \ 518 ${toString i} --value="${toString v}" 519 '') ([ cfg.hostName ] ++ cfg.config.extraTrustedDomains)); 520 521 in { 522 wantedBy = [ "multi-user.target" ]; 523 before = [ "phpfpm-nextcloud.service" ]; 524 path = [ occ ]; 525 script = '' 526 chmod og+x ${cfg.home} 527 528 ${optionalString (c.dbpassFile != null) '' 529 if [ ! -r "${c.dbpassFile}" ]; then 530 echo "dbpassFile ${c.dbpassFile} is not readable by nextcloud:nextcloud! Aborting..." 531 exit 1 532 fi 533 if [ -z "$(<${c.dbpassFile})" ]; then 534 echo "dbpassFile ${c.dbpassFile} is empty!" 535 exit 1 536 fi 537 ''} 538 ${optionalString (c.adminpassFile != null) '' 539 if [ ! -r "${c.adminpassFile}" ]; then 540 echo "adminpassFile ${c.adminpassFile} is not readable by nextcloud:nextcloud! Aborting..." 541 exit 1 542 fi 543 if [ -z "$(<${c.adminpassFile})" ]; then 544 echo "adminpassFile ${c.adminpassFile} is empty!" 545 exit 1 546 fi 547 ''} 548 549 ln -sf ${cfg.package}/apps ${cfg.home}/ 550 551 # create nextcloud directories. 552 # if the directories exist already with wrong permissions, we fix that 553 for dir in ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps; do 554 if [ ! -e $dir ]; then 555 install -o nextcloud -g nextcloud -d $dir 556 elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then 557 chgrp -R nextcloud $dir 558 fi 559 done 560 561 ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php 562 563 # Do not install if already installed 564 if [[ ! -e ${cfg.home}/config/config.php ]]; then 565 ${occInstallCmd} 566 fi 567 568 ${occ}/bin/nextcloud-occ upgrade 569 570 ${occ}/bin/nextcloud-occ config:system:delete trusted_domains 571 ${occSetTrustedDomainsCmd} 572 ''; 573 serviceConfig.Type = "oneshot"; 574 serviceConfig.User = "nextcloud"; 575 }; 576 nextcloud-cron = { 577 environment.NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config"; 578 serviceConfig.Type = "oneshot"; 579 serviceConfig.User = "nextcloud"; 580 serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${cfg.package}/cron.php"; 581 }; 582 nextcloud-update-plugins = mkIf cfg.autoUpdateApps.enable { 583 serviceConfig.Type = "oneshot"; 584 serviceConfig.ExecStart = "${occ}/bin/nextcloud-occ app:update --all"; 585 serviceConfig.User = "nextcloud"; 586 startAt = cfg.autoUpdateApps.startAt; 587 }; 588 }; 589 590 services.phpfpm = { 591 pools.nextcloud = { 592 user = "nextcloud"; 593 group = "nextcloud"; 594 phpPackage = phpPackage; 595 phpEnv = { 596 NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config"; 597 PATH = "/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin"; 598 }; 599 settings = mapAttrs (name: mkDefault) { 600 "listen.owner" = config.services.nginx.user; 601 "listen.group" = config.services.nginx.group; 602 } // cfg.poolSettings; 603 extraConfig = cfg.poolConfig; 604 }; 605 }; 606 607 users.users.nextcloud = { 608 home = "${cfg.home}"; 609 group = "nextcloud"; 610 createHome = true; 611 isSystemUser = true; 612 }; 613 users.groups.nextcloud.members = [ "nextcloud" config.services.nginx.user ]; 614 615 environment.systemPackages = [ occ ]; 616 617 services.nginx.enable = mkDefault true; 618 619 services.nginx.virtualHosts.${cfg.hostName} = let 620 major = toInt (versions.major cfg.package.version); 621 in { 622 root = cfg.package; 623 locations = { 624 "= /robots.txt" = { 625 priority = 100; 626 extraConfig = '' 627 allow all; 628 log_not_found off; 629 access_log off; 630 ''; 631 }; 632 "= /" = { 633 priority = 100; 634 extraConfig = '' 635 if ( $http_user_agent ~ ^DavClnt ) { 636 return 302 /remote.php/webdav/$is_args$args; 637 } 638 ''; 639 }; 640 "/" = { 641 priority = 900; 642 extraConfig = "rewrite ^ /index.php;"; 643 }; 644 "~ ^/store-apps" = { 645 priority = 201; 646 extraConfig = "root ${cfg.home};"; 647 }; 648 "^~ /.well-known" = { 649 priority = 210; 650 extraConfig = '' 651 absolute_redirect off; 652 location = /.well-known/carddav { 653 return 301 /remote.php/dav; 654 } 655 location = /.well-known/caldav { 656 return 301 /remote.php/dav; 657 } 658 location ~ ^/\.well-known/(?!acme-challenge|pki-validation) { 659 return 301 /index.php$request_uri; 660 } 661 try_files $uri $uri/ =404; 662 ''; 663 }; 664 "~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)".extraConfig = '' 665 return 404; 666 ''; 667 "~ ^/(?:\\.(?!well-known)|autotest|occ|issue|indie|db_|console)".extraConfig = '' 668 return 404; 669 ''; 670 "~ ^\\/(?:index|remote|public|cron|core\\/ajax\\/update|status|ocs\\/v[12]|updater\\/.+|oc[ms]-provider\\/.+|.+\\/richdocumentscode\\/proxy)\\.php(?:$|\\/)" = { 671 priority = 500; 672 extraConfig = '' 673 include ${config.services.nginx.package}/conf/fastcgi.conf; 674 fastcgi_split_path_info ^(.+?\.php)(\\/.*)$; 675 set $path_info $fastcgi_path_info; 676 try_files $fastcgi_script_name =404; 677 fastcgi_param PATH_INFO $path_info; 678 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 679 fastcgi_param HTTPS ${if cfg.https then "on" else "off"}; 680 fastcgi_param modHeadersAvailable true; 681 fastcgi_param front_controller_active true; 682 fastcgi_pass unix:${fpm.socket}; 683 fastcgi_intercept_errors on; 684 fastcgi_request_buffering off; 685 fastcgi_read_timeout 120s; 686 ''; 687 }; 688 "~ \\.(?:css|js|woff2?|svg|gif|map)$".extraConfig = '' 689 try_files $uri /index.php$request_uri; 690 expires 6M; 691 access_log off; 692 ''; 693 "~ ^\\/(?:updater|ocs-provider|ocm-provider)(?:$|\\/)".extraConfig = '' 694 try_files $uri/ =404; 695 index index.php; 696 ''; 697 "~ \\.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$".extraConfig = '' 698 try_files $uri /index.php$request_uri; 699 access_log off; 700 ''; 701 }; 702 extraConfig = '' 703 index index.php index.html /index.php$request_uri; 704 expires 1m; 705 add_header X-Content-Type-Options nosniff; 706 add_header X-XSS-Protection "1; mode=block"; 707 add_header X-Robots-Tag none; 708 add_header X-Download-Options noopen; 709 add_header X-Permitted-Cross-Domain-Policies none; 710 add_header X-Frame-Options sameorigin; 711 add_header Referrer-Policy no-referrer; 712 add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; 713 client_max_body_size ${cfg.maxUploadSize}; 714 fastcgi_buffers 64 4K; 715 fastcgi_hide_header X-Powered-By; 716 gzip on; 717 gzip_vary on; 718 gzip_comp_level 4; 719 gzip_min_length 256; 720 gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; 721 gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; 722 723 ${optionalString cfg.webfinger '' 724 rewrite ^/.well-known/host-meta /public.php?service=host-meta last; 725 rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; 726 ''} 727 ''; 728 }; 729 } 730 ]); 731 732 meta.doc = ./nextcloud.xml; 733}