Skip to content

docs: Add Caddy web server configuration (revives #9199)#14659

Open
Copilot wants to merge 3 commits intomasterfrom
copilot/improve-caddyfile-sample
Open

docs: Add Caddy web server configuration (revives #9199)#14659
Copilot wants to merge 3 commits intomasterfrom
copilot/improve-caddyfile-sample

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 28, 2026

Revives and fixes PR #9199, adding a complete Caddy 2.6+ + PHP-FPM configuration sample and documentation page for Nextcloud.

New files

  • Caddyfile.sample — complete working config covering compression, security headers, .well-known routing, asset caching, internal path blocking, and PHP-FPM passthrough
  • caddy.rst — documentation page modelled after nginx.rst

Fixes applied from original PR review

Issue Fix
Typo /corn.php /cron.php
:language: caddy (unknown Pygments lexer, build warning) :language: nginx
"webroot of your nginx installation" → "Caddy installation"
Subdir section hidden as RST comment Expanded into a visible section with handle_path + vars/env REQUEST_URI workaround and note on OVERWRITEWEBROOT in config.php
@assets header path-scoping syntax Simplified to one Cache-Control value with a comment for .woff2 override

Additions

  • FrankenPHP note: documents php_server as an alternative that eliminates manual rewrite rules; links to greyxor/nextcloud-docker as a reference implementation
  • caddy added to installation/index.rst toctree after nginx

☑️ Resolves

🖼️ Screenshots

✅ Checklist

  • I have built the documentation locally and reviewed the output
  • Screenshots are included for visual changes
  • I have not moved or renamed pages (or added a redirect if I did)
  • I have run codespell or similar and addressed any spelling issues
Original prompt

Background

This is a revival and improvement of PR #9199 (#9199), which adds a Caddy web server configuration sample for Nextcloud. That PR has been open since 2022 and has received 2 approvals (from @CarlSchwan and @ChristophWurst) but stalled due to a few fixable issues.

The configuration should also be inspired by the real-world Caddyfile used in the nextcloud-docker project by @GreyXor: https://gitlab.com/greyxor/nextcloud-docker/-/raw/main/rootfs/etc/frankenphp/Caddyfile?ref_type=heads

Files to create/modify

1. admin_manual/installation/Caddyfile.sample (new file)

Create this file with a complete, working Caddy + PHP-FPM configuration for Nextcloud. Start from the original PR's content and apply all of the following fixes and improvements:

Critical fixes:

  • Fix typo: the original has /corn.php which must be /cron.php

Content of the file (use this as the basis, improve as needed):

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`
		header *.woff2 Cache-Control "max-age=604800"  # Cache-Control policy borrowed from `.htaccess`
		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.p...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

Copilot AI and others added 2 commits April 28, 2026 08:38
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>
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>
Copilot AI changed the title [WIP] Revive and improve Caddyfile configuration for Nextcloud docs: Add Caddy web server configuration (revives #9199) Apr 28, 2026
Copilot AI requested a review from nextcloud-command April 28, 2026 08:41
@skjnldsv skjnldsv marked this pull request as ready for review April 28, 2026 08:43
@nextcloud-command nextcloud-command removed their request for review April 28, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants