From 6048a21b8514d616c098689e88227daaec654cee Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 08:35:20 +0000 Subject: [PATCH 1/3] Initial plan From a27bc4b682477bdf7669a846797f4a115d22e072 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 08:38:14 +0000 Subject: [PATCH 2/3] docs: add Caddy web server configuration sample and documentation Agent-Logs-Url: https://github.com/nextcloud/documentation/sessions/9a2e3f3e-0221-4549-a579-40470c763467 Co-authored-by: nextcloud-command <88102737+nextcloud-command@users.noreply.github.com> --- admin_manual/installation/Caddyfile.sample | 157 +++++++++++++++++++++ admin_manual/installation/caddy.rst | 102 +++++++++++++ admin_manual/installation/index.rst | 1 + 3 files changed, 260 insertions(+) create mode 100644 admin_manual/installation/Caddyfile.sample create mode 100644 admin_manual/installation/caddy.rst diff --git a/admin_manual/installation/Caddyfile.sample b/admin_manual/installation/Caddyfile.sample new file mode 100644 index 00000000000..24cd072a415 --- /dev/null +++ b/admin_manual/installation/Caddyfile.sample @@ -0,0 +1,157 @@ +cloud.example.com # Public server hostname + +request_body { + max_size 10G +} + +# Enable compression but do not remove ETag headers +encode { + zstd + gzip 4 + + minimum_length 256 + + match { + header Content-Type application/atom+xml + header Content-Type application/javascript + header Content-Type application/json + header Content-Type application/ld+json + header Content-Type application/manifest+json + header Content-Type application/rss+xml + header Content-Type application/vnd.geo+json + header Content-Type application/vnd.ms-fontobject + header Content-Type application/wasm + header Content-Type application/x-font-ttf + header Content-Type application/x-web-app-manifest+json + header Content-Type application/xhtml+xml + header Content-Type application/xml + header Content-Type font/opentype + header Content-Type image/bmp + header Content-Type image/svg+xml + header Content-Type image/x-icon + header Content-Type text/cache-manifest + header Content-Type text/css + header Content-Type text/plain + header Content-Type text/vcard + header Content-Type text/vnd.rim.location.xloc + header Content-Type text/vtt + header Content-Type text/x-component + header Content-Type text/x-cross-domain-policy + } +} + +# Add security-related headers +header { + Referrer-Policy no-referrer + Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" + X-Content-Type-Options nosniff + X-Download-Options noopen + X-Frame-Options SAMEORIGIN + X-Permitted-Cross-Domain-Policies none + X-Robots-Tag "noindex, nofollow" + X-XSS-Protection "1; mode=block" + # Remove X-Powered-By header (already removed by default in newer Caddy) + -X-Powered-By +} + +# Path to the root of your installation +root * /var/www/nextcloud + +route { + # Rule borrowed from `.htaccess` to handle Microsoft DAV clients + @msftdavclient { + header User-Agent DavClnt* + path / + } + redir @msftdavclient /remote.php/webdav/ temporary + + route /robots.txt { + skip_log + file_server + } + + # Add exception for `/.well-known` so that clients can still access it + # despite the existence of the `error @internal 404` rule which would + # otherwise handle requests for `/.well-known` below + route /.well-known/* { + redir /.well-known/carddav /remote.php/dav/ permanent + redir /.well-known/caldav /remote.php/dav/ permanent + + @well-known-static path \ + /.well-known/acme-challenge /.well-known/acme-challenge/* \ + /.well-known/pki-validation /.well-known/pki-validation/* + route @well-known-static { + try_files {path} {path}/ =404 + file_server + } + + redir * /index.php{path} permanent + } + + # Block access to internal/sensitive paths + @internal path \ + /build /build/* \ + /tests /tests/* \ + /config /config/* \ + /lib /lib/* \ + /3rdparty /3rdparty/* \ + /templates /templates/* \ + /data /data/* \ + \ + /.* \ + /autotest* \ + /occ* \ + /issue* \ + /indie* \ + /db_* \ + /console* + error @internal 404 + + @assets { + path *.css *.js *.svg *.gif *.png *.jpg *.jpeg *.ico *.wasm *.tflite *.map *.wasm2 + file {path} # Only if requested file exists on disk, otherwise /index.php will handle it + } + route @assets { + header Cache-Control "max-age=15552000" # Cache-Control policy borrowed from `.htaccess` + # Note: to give .woff2 files a shorter TTL, add a nested route for *.woff2 + # with `header Cache-Control "max-age=604800"` before this one. + skip_log # Optional: Don't log access to assets + file_server { + precompressed gzip + } + } + + # Rule borrowed from `.htaccess` + redir /remote/* /remote.php{path} permanent + + # Serve found static files, falling through to PHP handler if not found + try_files {path} {path}/ + @notphpordir not path /*.php /*.php/* / /*/ + file_server @notphpordir { + pass_thru + } + + # Required for legacy support + # + # Rewrites all other requests to be prepended with "/index.php" unless they already + # match a known PHP entry point. + @unknownphppath not path \ + /index.php /index.php/* \ + /remote.php /remote.php/* \ + /public.php /public.php/* \ + /cron.php /cron.php/* \ + /core/ajax/update.php /core/ajax/update.php/* \ + /status.php /status.php/* \ + /ocs/v1.php /ocs/v1.php/* \ + /ocs/v2.php /ocs/v2.php/* \ + /updater/*.php /updater/*.php/* \ + /ocm-provider/*.php /ocm-provider/*.php/* \ + /ocs-provider/*.php /ocs-provider/*.php/* + rewrite @unknownphppath /index.php{path} + + # Let everything else be handled by the PHP-FPM component + php_fastcgi nextcloud:9000 { + env modHeadersAvailable true # Avoid sending the security headers twice + env front_controller_active true # Enable pretty urls + } +} diff --git a/admin_manual/installation/caddy.rst b/admin_manual/installation/caddy.rst new file mode 100644 index 00000000000..001137d77ef --- /dev/null +++ b/admin_manual/installation/caddy.rst @@ -0,0 +1,102 @@ +=================== +Caddy configuration +=================== + +.. warning:: + Please note that webservers other than Apache 2.x are not officially supported. + +.. note:: + This page covers example Caddy configuration to run a Nextcloud server. + These configuration examples were originally provided by + `@ntninja `_ based on the :doc:`nginx` sample and + are exclusively community-maintained. (Thank you contributors!) + +- This guide assumes you are using Caddy 2.6 or later and the presented sample + configuration will not work on older versions without modification. +- Caddy takes care of TLS certificate configuration and HTTP-to-HTTPS redirects + automatically, so that is not covered here. +- The example configuration makes use of the `route `_ + directive which disables all directive reordering usually done by Caddy. This + means that anything within that block should be read strictly top-to-bottom + unlike what you may be used to from NGINX or regular (non-route) Caddy + configurations. +- Be careful about line breaks if you copy the examples, as long lines may be + broken for page formatting. +- Some environments might need a ``cgi.fix_pathinfo`` set to ``1`` in their + ``php.ini``. + +.. note:: + If you are using **FrankenPHP** (an application server built on top of Caddy), + you can use the ``php_server`` directive instead of the ``php_fastcgi``-based + approach described on this page. FrankenPHP handles the try-files logic and PHP + routing internally, which greatly simplifies the configuration. See the + `FrankenPHP documentation `_ and a community + example at https://gitlab.com/greyxor/nextcloud-docker for reference. + +Nextcloud in the webroot of Caddy +---------------------------------- + +The following configuration should be used when Nextcloud is placed in the +webroot of your Caddy installation. In this example it is +``/var/www/nextcloud`` and it is accessed via ``http(s)://cloud.example.com/`` + +.. literalinclude:: Caddyfile.sample + :language: nginx + +Nextcloud in a subdir of the Caddy webroot +------------------------------------------ + +Serving Nextcloud from a subdirectory (e.g. ``https://cloud.example.com/nextcloud/``) +requires extra steps with Caddy compared to NGINX, due to the way Caddy's +``handle_path`` strips the prefix from ``PATH_INFO`` but not from ``REQUEST_URI``, +while Nextcloud relies on ``REQUEST_URI``. + +The recommended approach is: + +1. Set ``OVERWRITEWEBROOT=/nextcloud`` in your Nextcloud or PHP-FPM configuration. +2. Wrap the main Caddyfile configuration in a ``handle_path /nextcloud/* { … }`` block, + or use ``uri strip_prefix /nextcloud``. +3. Capture the rewritten URI before the PHP handler and pass it as ``REQUEST_URI``: + +.. code-block:: nginx + + handle_path /nextcloud/* { + # … (place the route block contents here) … + + vars rewritten_uri {uri} + + # Let everything else be handled by the PHP-FPM component + php_fastcgi app:9000 { + env modHeadersAvailable true + env front_controller_active true + env REQUEST_URI {vars.rewritten_uri} + } + } + +.. note:: + With FrankenPHP's ``php_server`` directive and the + ``htaccess.IgnoreFrontController`` option, subdirectory support is handled + automatically without these workarounds. + +Tips and tricks +--------------- + +Suppressing log messages +^^^^^^^^^^^^^^^^^^^^^^^^ + +If you're seeing meaningless messages in your logfile, for example ``client +denied by server configuration: /var/www/data/htaccesstest.txt``, add this +section to your Caddy configuration to suppress them: + +.. code-block:: nginx + + route { + # … + + route /data/htaccesstest.txt { + skip_log # Silences logging for the matched path + file_server + } + + # … + } diff --git a/admin_manual/installation/index.rst b/admin_manual/installation/index.rst index dffbf18f198..937682eeffb 100644 --- a/admin_manual/installation/index.rst +++ b/admin_manual/installation/index.rst @@ -14,6 +14,7 @@ Installation and server configuration automatic_configuration selinux_configuration nginx + caddy harden_server server_tuning From 5c5937d8a34afa654943d98848edd8c9f45e50de Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 08:39:15 +0000 Subject: [PATCH 3/3] docs: fix broken link and clarify OVERWRITEWEBROOT in caddy.rst Agent-Logs-Url: https://github.com/nextcloud/documentation/sessions/9a2e3f3e-0221-4549-a579-40470c763467 Co-authored-by: nextcloud-command <88102737+nextcloud-command@users.noreply.github.com> --- admin_manual/installation/caddy.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/admin_manual/installation/caddy.rst b/admin_manual/installation/caddy.rst index 001137d77ef..b4764fe3bb9 100644 --- a/admin_manual/installation/caddy.rst +++ b/admin_manual/installation/caddy.rst @@ -8,7 +8,7 @@ Caddy configuration .. note:: This page covers example Caddy configuration to run a Nextcloud server. These configuration examples were originally provided by - `@ntninja `_ based on the :doc:`nginx` sample and + `@ntninja `_ based on the :doc:`nginx` sample and are exclusively community-maintained. (Thank you contributors!) - This guide assumes you are using Caddy 2.6 or later and the presented sample @@ -53,7 +53,7 @@ while Nextcloud relies on ``REQUEST_URI``. The recommended approach is: -1. Set ``OVERWRITEWEBROOT=/nextcloud`` in your Nextcloud or PHP-FPM configuration. +1. Set ``'overwritewebroot' => '/nextcloud'`` in your Nextcloud ``config/config.php``. 2. Wrap the main Caddyfile configuration in a ``handle_path /nextcloud/* { … }`` block, or use ``uri strip_prefix /nextcloud``. 3. Capture the rewritten URI before the PHP handler and pass it as ``REQUEST_URI``: