V2: WordPress Caddyfile

1. My Caddy version (caddy version)

v2.0.0-rc.1 h1:DxUlg4kMisXwXVnWND7KEPl1f+vjFpIOzYpKpfmwyj8=

2. How I run Caddy:

a. System environment:

Hardware:

  • AMD Ryzen 2700
  • 32GBs of DDR4 RAM

Software:

  • Windows 10 LTSC 1809, build 17763.1131
  • PHP 7.4.1 (installed via Chocolatey)
  • MariaDB 10.5 (installed via Chocolatey)
  • WordPress 5.3.2

b. Command:

caddy run

c. Service/unit/compose file:

I just have one general Caddyfile I use to import the rest:

import C:/Users/Ryan/www/*/dev.Caddyfile

d. My complete Caddyfile or JSON config:

:9001 {
  root * C:/Users/Ryan/www/wp
  php_fastcgi 127.0.0.1:9000

  encode gzip
  file_server
}

3. The problem I’m having:

I’m trying to migrate a WordPress website from Caddy v1 to Caddy v2. The website doesn’t work as it should (it loads, but anything with a query in the URL isn’t parsed).
Whenever I try to use the administration, and it has a query on the URL, it doesn’t work either, trying to process the query for about 5 mins, then dropping it.
It worked just fine with Caddy v1:

:9001 {
  root C:/Users/Ryan/www/wp
  gzip
  fastcgi / 127.0.0.1:9000
    
  rewrite {
    if {path} not_match ^\/wp-admin
    to {path} {path}/ /index.php?{query}
  }
}

4. Error messages and/or full log output:

Multiple HTTP Error 500 after the server timeout.

5. What I already tried:

It seems to be related to the if {path} not_match ^\/wp-admin directive and the {query} placeholder used in the old v1 Caddyfile. I’ve tried to replicate the config under v2 after reading the docs multiple times, to no avail:

:9001 {
  root * C:/Users/Ryan/www/wp

  # Add trailing slash for directory requests
  @canonicalPath {
    file {
      try_files {path}/index.php
    }
    not {
      path */
    }
  }
  redir @canonicalPath {path}/ 308

  # If the requested file does not exist, try index files
  @wp_rewrite { 
    not {
      path /wp-admin/*
      file {
        try_files {path} {path}/index.php?{query} index.php?{query}
      }
    }
  }
  rewrite @wp_rewrite {http.matchers.file.relative}

  # Proxy PHP files to the FastCGI responder
  @phpFiles {
    path *.php
  }
  reverse_proxy @phpFiles 127.0.0.1:9000 {
    transport fastcgi {
      split .php
    }
  }

  encode gzip
  file_server
}

6. Links to relevant resources:

This was the v1 Caddyfile I’ve used until now: examples/Caddyfile at master · caddyserver/examples · GitHub

This is what I based my second attempt on:

Okay let’s start from a minimal configuration.

What happens if you try this:

:9001 {
  root * C:/Users/Ryan/www/wp

  php_fastcgi 127.0.0.1:9000

  encode gzip
  file_server
}

Hi!
That is the configuration file I already have. The issue remains the same: the request timeouts after 3 to 5 minutes if it has any query parameter (for instance: http://127.0.0.1:9001/wp-admin/update-core.php?action=do-translation-upgrade), returning a HTTP 500 error.

What’s the HTTP 500 error? Check your logs, it should reveal more information about it.

1 Like

To clarify, I think that simple Caddyfile should work just fine. For context, another user confirmed recently that it worked for them:

The only thing you might want to add is a rule to block .php files from the /uploads directory:

respond /uploads/*.php 404

I feel that the HTTP 500 error is unrelated to the way Caddy is passing the request to your server, but instead some other issue. Best to find the error logs and see what it says.

2 Likes

Here’s an example of WordPress trying to do a cronjob (which also fails, this one just timeouts after 30 seconds):

2020/04/06 17:39:57.005 e[31mERRORe[0m  http.log.access handled request {"request": {"method": "POST", "uri": "/wp-cron.php?doing_wp_cron=1586194795.4079759120941162109375", "proto": "HTTP/1.1", "remote_addr": "127.0.0.1:55850", "host": "127.0.0.1:9001", "headers": {"User-Agent": ["WordPress/5.4; http://127.0.0.1:9001"], "Accept": ["*/*"], "Accept-Encoding": ["deflate, gzip"], "Referer": ["http://127.0.0.1:9001/wp-cron.php?doing_wp_cron=1586194795.4079759120941162109375"], "Connection": ["close"], "Content-Length": ["0"], "Content-Type": ["application/x-www-form-urlencoded"]}}, "common_log": "127.0.0.1 - - [06/Apr/2020:19:39:57 +0200] \"POST /wp-cron.php?doing_wp_cron=1586194795.4079759120941162109375 HTTP/1.1\" 500 1425", "latency": 1.5937577, "size": 1425, "status": 500, "resp_headers": {"Status": ["500 Internal Server Error"], "Expires": ["Wed, 11 Jan 1984 05:00:00 GMT"], "Cache-Control": ["no-transform, no-cache, no-store, must-revalidate"], "Vary": ["Accept-Encoding"], "Server": ["Caddy"], "Set-Cookie": ["PHPSESSID=no2okl5vh57vh7crf8ikjtthjb; path=/"], "Pragma": ["no-cache"], "Content-Type": ["text/html; charset=UTF-8"], "Content-Encoding": ["gzip"], "X-Powered-By": ["PHP/7.4.3"]}}

Thanks for the tip! I’ll include it once I get it working.

1 Like

I’m looking for the PHP error logs. php-fpm must be logging the error somewhere.

Could you try running:

php --info | findstr /r /c:"error_log"

This might show you where the logs are configured to be written to.

1 Like

I used scoop to install PHP on my windows machine (I prefer it over chocolatey for many reasons)

$ php-cgi -i | grep error_log
<tr><td class="e">error_log</td><td class="v"><i>no value</i></td><td class="v"><i>no value</i></td></tr>

Looks like the default installation of php doesn’t enable error_log.

Please add a line to your conf file (not sure where chocolatey installs PHP), like error_log = "C:\some\path\php-cgi.log"

1 Like

My bad, I thought you were referring to the Caddy log. The PHP-FPM error log just repeats itself over and over:

[06-Apr-2020 18:00:58 UTC] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in C:\Users\Ryan\www\wp\wp-includes\Requests\Transport\cURL.php on line 163
[06-Apr-2020 18:03:59 UTC] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in C:\Users\Ryan\www\wp\wp-includes\Requests\Transport\cURL.php on line 163
[06-Apr-2020 18:04:02 UTC] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in C:\Users\Ryan\www\wp\wp-includes\Requests\Transport\cURL.php on line 163

I have the cURL extension enabled, and cURL installed in Windows.

Okay, then that’s definitely not an issue with Caddy, that means that your cron is attempting to make an HTTP request using curl to somewhere but it’s timing out. Maybe you can add a debug line just before that spot to see what the request address is that your code is trying to hit? Something like error_log($url); I don’t know the WordPress codebase very well.

Edit: I think this is the code: cURL.php in tags/5.4/src/wp-includes/Requests/Transport – WordPress Trac so yes, error_log($url); somewhere before curl_exec() should clarify what’s going on, I hope.

2 Likes

Thank you!
I’ve solved the issue by checking the URLs being fetched via cURL, and the Hummingbird plugin (WordPress) was stuck in a loop calling the URLs over and over.

As you’ve said, this has nothing to do with Caddy v2, but it was somehow working with v1.

2 Likes

Great! Glad you figured it out!

1 Like

Quick update on the issue: WordPress 5.4 seems to not be fully compatible with PHP 7.4 just yet. This seems to definitely be the issue, as downgrading to 7.3.15 solved every single problem.

3 Likes

A post was split to a new topic: Wordpress + secure connections

WordPress is officially compatible with PHP 7.4 since WordPress 5.3 : Version 5.3 – WordPress.org Forums

I used PHP 7.4 before that and had no issue either. I don’t think it’s the problem for you.

3 Likes

I have try, and is working.
Please give it a short


www.yourdomian.com {
root * /usr/local/www/wordpress
log /var/log/caddy_log.log

        encode gzip
        php_fastcgi 127.0.0.1:9000

        # Prevent malicious PHP uploads from running
        @uploads {
          path_regexp path /uploads\/(.*)\.php
        }
        rewrite @uploads /

        @wp-admin {
          path  not ^\/wp-admin/*
        }
        rewrite @wp-admin {path}/index.php?{query}
        file_server
}

That looks good!

One note, your log directive isn’t exactly right. I think you’re looking for this:

log {
    output file /var/log/caddy_log.log
}
1 Like

What is the purpose of this block?

@wp-admin {
  path not ^\/wp-admin/*
}
rewrite @wp-admin {path}/index.php?{query}

A working WordPress Caddyfile would be a good thing to add to our wiki.

1 Like

I had a question from last month. Caddy 2 wordpress config

I strongly recommend you to run it on unix sockets with

php_fastcgi unix//run/php/php7.x-fpm.sock
( where x is your php-fpm version.)

Then change your php-fpm www.conf with

     listen-owner: caddy 
     listen-group: caddy
1 Like