Issues porting v1 dokuwiki config to v2

1. Caddy version (caddy version):

I installed it from the AUR and caddy version only says (devel), but the package is versioned 2.0.0-2, last updated 2020-05-15.

2. How I run Caddy:

systemd - the AUR package provides a service file.

a. System environment:

Arch Linux, last updated today.

b. Command:

sudo systemctl start caddy

c. Service/unit/compose file:

Description=Caddy Web Server

ExecStart=/usr/bin/caddy run --config /etc/caddy/Caddyfile --resume --environ
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
ExecStop=/usr/bin/caddy stop

# Hardening options
ReadWritePaths=/var/lib/caddy /var/log/caddy /srv/http


d. My complete Caddyfile or JSON config:

(common) {
	encode zstd gzip
	header * {
		Strict-Transport-Security "max-age=17280000"
		Referrer-Policy "strict-origin-when-cross-origin"
		Server "Apache/2.4.9 (Emacs/GNU/Hurd 0.6)"
		X-Content-Type-Options nosniff

	@mp4 { path *.mp4 }
	header @mp4 Content-Type video/mp4
	@bin { path *.bin }
	header @bin Content-Type application/octet-stream

	log {
		level DEBUG

	import common
	root * /data/files/dokuwiki
	php_fastcgi /var/run/php-fpm/php-fpm.sock
	@forbidden {
		path /data/* /conf/* /inc/* /vendor/* /install.php
	respond @forbidden 403 {
		body "No."
	@media { 
		path_regexp media "/_media/(.*)"
	rewrite @media /lib/exe/fetch.php?media={}
	@detail { 
		path_regexp detail "/_detail/(.*)"
	rewrite @detail /lib/exe/detail.php?media={http.regexp.detail.1}
	@export { 
		path_regexp export "/_export/([^/]+)/(.*)"
	rewrite @export /doku.php?do=export_{http.regexp.export.1}&id={http.regexp.export.2}
	@regular {
		not path /lib/*
		path_regexp regular "/(.*)"
        rewrite @regular /doku.php?id={http.regexp.regular.1}&{query}

3. The problem I’m having:

I previously had a dokuwiki install using PHP-FPM behind caddy (along with some other services) using the example configuration linked below (modified slightly for my environment). I upgraded to caddy v2 today due to an unrelated issue with websockets (not resolved, still trying to figure it out).
I’ve attempted to port this configuration file to v2, but am not sure how to do it, as v2 seems pretty different and I don’t really understand how to translate things. My attempt at it so far is shown above, and it loads without errors, but for all URLs I’ve tried it produces responses like this in curl:

HTTP/2 200 
referrer-policy: strict-origin-when-cross-origin
server: Apache/2.4.9 (Emacs/GNU/Hurd 0.6)
strict-transport-security: max-age=17280000
x-content-type-options: nosniff
date: Sat, 06 Jun 2020 17:49:22 GMT

and is a blank screen in the browser. I’m not sure why this is, or how/if there’s any way to debug it.

4. Error messages and/or full log output:

HTTP requests produce blank output as shown above. There are no errors on (re)load. Here’s a log line from caddy produced when I try it:

{"level":"info","ts":1591467089.5940807,"logger":"http.log.access.log0","msg":"handled request","request":{"method":"GET","uri":"/_media/","proto":"HTTP/2.0","remote_addr":"[REDACTED]:37076","host":"notes.[REDACTED]","headers":{"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"],"Accept-Language":["en-US,en;q=0.5"],"Accept-Encoding":["gzip, deflate, br"],"Dnt":["1"],"Pragma":["no-cache"],"Te":["trailers"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0"],"Cookie":["[REDACTED]"],"Upgrade-Insecure-Requests":["1"],"Cache-Control":["no-cache"]},"tls":{"resumed":false,"version":772,"ciphersuite":4865,"proto":"h2","proto_mutual":true,"server_name":"notes.[REDACTED]"}},"common_log":"[REDACTED] - - [06/Jun/2020:18:11:29 +0000] \"GET /_media/ HTTP/2.0\" 0 0","duration":0.000149868,"size":0,"status":0,"resp_headers":{"Server":["Apache/2.4.9 (Emacs/GNU/Hurd 0.6)"],"Referrer-Policy":["strict-origin-when-cross-origin"],"Strict-Transport-Security":["max-age=17280000"],"X-Content-Type-Options":["nosniff"]}}

5. What I already tried:

I’ve tried making some changes to the config there, but don’t know how to make it work correctly. I may just have to temporarily reverse proxy to a nginx instance instead, since dokuwiki has configuration for this documented.

6. Links to relevant resources:

“status”: 0,

From your error log. Makes me think that no directive is acting as a terminating handler for that request. The URI was /_media/. It should’ve been rewritten to /lib/exe/fetch.php?media=, which should’ve been picked up by the php_fastcgi handler.

It’s not quite accurately translated, though, and the original example is not ideal. I’m going to give it a crack. {
  root * /path/to/dokuwiki
  encode gzip
  php_fastcgi unix//var/run/php-fpm/php-fpm.sock

  @forbidden {
    path /data/* /conf/* /inc/* /vendor/* /install.php
  respond @forbidden "No." 403

  rewrite /_media* /lib/exe/fetch.php?media={path}
  rewrite /_detail* /lib/exe/detail.php?media={path}
  @export {
    path /_export*
    path_regexp export /([^/]+)/(.*)
  rewrite @export /doku.php?do=export_{http.regexp.export.1}&id={http.regexp.export.2}
  try_files {uri} /doku.php?id={path}&{query}
  • Got rid of a bunch of unnecessary regex checking
  • Added try_files instead of final rewrite
  • Added file_server to handle non-PHP requests (v2 does not have static file server handler enabled by default)
  • Unix socket path prefix unix// (see Conventions — Caddy Documentation)
1 Like

Oh! I know what the issue is… I think?

/var/run/php-fpm/php-fpm.sock looks like an exact path matcher. So the PHP handler is only ever acting for a request the client makes specifically for this exact path. It also has no upstream. I know that sounds weird, but a matcher almost always comes as the first parameter to a directive; if it starts with a forward slash, or an asterisk, Caddy will consume it as an inline/unnamed matcher.

That would mean you get responses with Status 0, which means no terminating handler ever touched it; the PHP handler is scoped out by that path (since you’re not requesting that exact path) and there’s no active static file server in v2 by default. Status 0 is interpreted by some browsers as Status 200 OK, I understand.

In my total rewrite attempt, I prefix this with unix// (to match the network address convention) which precludes it being consumed as an unnamed matcher.

1 Like

Which is, in fact, required when using any network type other than TCP :slight_smile:

And just to clarify, the prefix is technically unix/, not unix// – the second slash is part of the path.

1 Like

Aye - the convention docs are pretty clear regarding that one, the string must be in the form network/address, where unix/ is the network and /path/to/php.sock would be the address; I wrote above that I prefixed it with unix// but it would have been more correct to say I prefixed it with just unix/.

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.