{ config, pkgs, ... }: let myPhp = pkgs.php83.buildEnv { extensions = { enabled, all }: with all; [ imagick opcache apcu redis memcached ] ++ enabled; extraConfig = '' opcache.enable=1 opcache.enable_cli=1 opcache.interned_strings_buffer=32 opcache.max_accelerated_files=15000 opcache.memory_consumption=256 opcache.save_comments=1 opcache.validate_timestamps=0 opcache.revalidate_freq=60 memory_limit=5G post_max_size=5G upload_max_filesize=5G output_buffering=0 redis.session.locking_enabled=1 redis.session.lock_retries=-1 redis.session.lock_wait_time=10000 apc.enable_cli=1 ''; }; occ = pkgs.writeScriptBin "nextcloud-occ" '' #! ${pkgs.runtimeShell} cd /var/www/nextcloud sudo=exec 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="/var/www/nextcloud/config" $sudo \ ${myPhp}/bin/php \ occ "$@" ''; daf = pkgs.writeScriptBin "nextcloud-daf" '' #! ${pkgs.runtimeShell} cd /var/www/nextcloud-tools/rescue sudo=exec 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="/var/www/nextcloud/config" $sudo \ ${myPhp}/bin/php \ decrypt-all-files.php "$@" ''; phpfpmSocketName = "/run/phpfpm/nextcloud.sock"; in { users.groups.nextcloud.members = [ "nextcloud" "nginx" ]; services.nginx.virtualHosts."cloud.stubbe.rocks" = { enableACME = true; forceSSL = true; serverName = "cloud.stubbe.rocks"; root = "/var/www/nextcloud/"; extraConfig = '' index index.php index.html /index.php$request_uri; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header X-Robots-Tag "noindex, nofollow"; add_header X-Download-Options noopen; add_header X-Permitted-Cross-Domain-Policies none; add_header X-Frame-Options sameorigin; add_header Referrer-Policy no-referrer; add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; client_max_body_size 1024M; fastcgi_buffers 64 4K; fastcgi_hide_header X-Powered-By; gzip on; gzip_vary on; gzip_comp_level 4; gzip_min_length 256; gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; 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; rewrite ^/.well-known/host-meta /public.php?service=host-meta last; rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; ''; locations = { "= /robots.txt" = { priority = 100; extraConfig = '' allow all; access_log off; ''; }; "= /" = { priority = 100; extraConfig = '' if ( $http_user_agent ~ ^DavClnt ) { return 302 /remote.php/webdav/$is_args$args; } ''; }; "/" = { priority = 900; extraConfig = "rewrite ^ /index.php;"; }; "~ ^/store-apps" = { priority = 201; extraConfig = "root /var/lib/nextcloud;"; }; "~ ^/nix-apps" = { priority = 201; extraConfig = "root /var/lib/nextcloud;"; }; "^~ /.well-known" = { priority = 210; extraConfig = '' absolute_redirect off; location = /.well-known/carddav { return 301 /remote.php/dav/; } location = /.well-known/caldav { return 301 /remote.php/dav/; } location ~ ^/\.well-known/(?!acme-challenge|pki-validation) { return 301 /index.php$request_uri; } try_files $uri $uri/ =404; ''; }; "~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)".extraConfig = '' return 404; ''; "~ ^/(?:\\.(?!well-known)|autotest|occ|issue|indie|db_|console)".extraConfig = '' return 404; ''; "~ ^\\/(?:index|remote|public|cron|core\\/ajax\\/update|status|ocs\\/v[12]|updater\\/.+|ocs-provider\\/.+|.+\\/richdocumentscode\\/proxy)\\.php(?:$|\\/)" = { priority = 500; extraConfig = '' include ${config.services.nginx.package}/conf/fastcgi.conf; fastcgi_split_path_info ^(.+?\.php)(\\/.*)$; set $path_info $fastcgi_path_info; try_files $fastcgi_script_name =404; fastcgi_param PATH_INFO $path_info; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param HTTPS "on"; fastcgi_param modHeadersAvailable true; fastcgi_param front_controller_active true; fastcgi_pass unix:${phpfpmSocketName}; fastcgi_intercept_errors on; fastcgi_request_buffering off; fastcgi_read_timeout 120s; ''; }; "~ \\.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map|ogg|flac)$".extraConfig = '' try_files $uri /index.php$request_uri; expires 6M; access_log off; location ~ \.mjs$ { default_type text/javascript; } location ~ \.wasm$ { default_type application/wasm; } ''; "~ ^\\/(?:updater|ocs-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; ''; "~ \.(otf|woff2?)$".extraConfig = '' try_files $uri /index.php$request_uri; expires 7d; # Cache-Control policy borrowed from `.htaccess` access_log off; # Optional: Don't log access to assets ''; }; }; environment.systemPackages = [ occ daf ]; # Option I: PHP-FPM pool for Nextcloud services.phpfpm.pools.nextcloud = let phpfpmUser = "nextcloud"; phpfpmGroup = "nextcloud"; server = "nginx"; in { phpPackage = myPhp; settings = { "listen" = "${phpfpmSocketName}"; "listen.owner" = "${server}"; "listen.group" = "${server}"; "user" = "${phpfpmUser}"; "group" = "${phpfpmGroup}"; "pm" = "dynamic"; "pm.max_children" = "120"; "pm.start_servers" = "12"; "pm.min_spare_servers" = "6"; "pm.max_spare_servers" = "18"; }; phpEnv = { NEXTCLOUD_CONFIG_DIR = "/var/www/nextcloud/config"; PATH = "/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin"; }; }; services.cron.enable = true; services.redis.servers."".enable = true; systemd.timers.nextcloud-cron = { wantedBy = [ "timers.target" ]; timerConfig.OnBootSec = "5m"; timerConfig.OnUnitActiveSec = "15m"; timerConfig.Unit = "nextcloud-cron.service"; }; systemd.services.nextcloud-cron = { environment.NEXTCLOUD_CONFIG_DIR = "/var/www/nextcloud/config"; serviceConfig.Type = "oneshot"; serviceConfig.User = "nextcloud"; serviceConfig.ExecStart = "${myPhp}/bin/php --define apc.enable_cli=1 -f /var/www/nextcloud/cron.php"; }; }