Skip to content
Grav 2.0 is officially stable. Read the announcement →
Support

Migrate with Caddy

Started by Paul Hodges 4 weeks ago · 19 replies · 481 views
4 weeks ago

I have Grav running just fine under the current version of Caddy. However, when I attempt to run the Grav migration, the initial call to Migrate.PHP returns 500. I'm at a bit of a loss how to start debugging this.

Paul

4 weeks ago

Are you talking about the 'staged' grav-2 site? Where exactly are you seeing the 500 error?

4 weeks ago

Yes. I click the "start migration" button from the 1.7 dashboard, and on the next page the "stage and start wizard" button, and then immediately get a popup box new blank page with a 500 message and a button to try again. Looking at the browser console I see the only call made is to migrate.php with a great long parameter.

Paul

last edited 07/27/26 by Paul Hodges
3 weeks ago

Thanks for the detail, that helped. I spent some time on this today and came back with two things: one I couldn't reproduce, and one I did find, which you'll want to act on regardless.

First the 500. I set up a Caddy + php-fpm site using Grav's own bundled webserver-configs/Caddyfile, staged a migration, and migrate.php loaded fine on PHP 8.3. So there's nothing about Caddy itself that breaks the wizard, and since you're getting the 500 instantly on the first wizard page (before any of the long work runs) it isn't the execution-timeout problem we've seen on some hosts either.

What I can tell you is why you had nothing to go on. migrate.php runs standalone, with no Grav behind it to catch an error and log it, so on any normal production host a PHP error came back as a completely empty 500. No message, nothing to report. That's on us, and I've just fixed it: the wizard now catches its own fatals and prints the error, the file and line, your PHP version and webserver, and the path to your PHP error log. That ships in migrate-grav 1.0.11. Update the plugin and hit the wizard again and it should tell you what's actually wrong instead of a blank page.

If you want to get ahead of it before then, the answer is already sitting in your PHP-FPM error log (not Caddy's access log, Caddy only sees the empty 500). Grab the last few lines from it right after you reproduce, paste them here, and I'll tell you what it is.

Now the part you should act on today. While testing I found that the Caddyfile we bundle with Grav doesn't protect anything at all. The security rules in it were written in nginx's regex style, but Caddy's path matcher is literal, so every one of those rules matches nothing and silently does nothing. On a stock Caddy site using that file I was able to fetch, over plain HTTP with no login:

  • user/accounts/*.yaml, which is your email address and password hash
  • user/config/*.yaml
  • logs/grav.log
  • composer.lock, page markdown, and the whole system/ and vendor/ folders

All of those return 403 on Apache. This is fixed in develop and goes out in Grav 2.0.15, but if you're using our bundled Caddyfile, please don't wait for the release. The fix is to write the rules as named path_regexp matchers that answer 403 themselves, inside a route block so they run before the catch-all rewrite:

TXT
@denied_dirs path_regexp (?i)^/(\.git|cache|bin|logs|backups?|tests)/
@denied_user_config path_regexp (?i)^/user/(config|env)/
@denied_dotfiles path_regexp (?i)(^|/)\.[^/]+$

route {
    respond @denied_dirs 403
    respond @denied_user_config 403
    respond @denied_dotfiles 403

    try_files {path} {path}/ /index.php?_url={uri}&{query}
    php_fastcgi 127.0.0.1:9000
    file_server
}

That's an abbreviated version, the full one is in webserver-configs/Caddyfile on develop.

This one matters for your migration specifically. The wizard writes a .migrating file at your webroot holding the token that is the only thing guarding migrate.php, and with the old Caddyfile that file is readable by anyone. The dotfile rule above covers it.

Post those php-fpm log lines when you get a chance and we'll get your 500 sorted.

3 weeks ago

Thanks for that - it's bedtime here now, but I'll try it again tomorrow.

I can't look at a php-fpm log as I don't have one - a crucial thing I didn't mention is that my server runs Windows, so there is no official php-fpm available. But I have a script which someone wrote to do the same job (for all I know I could be the only other person using it), and I could probably add some logging to that if necessary.

As for security... I had considerable experience with Caddy before using it to serve Grav, so I wrote the suggested checks myself in my own style - I think before you published your version. When I checked, it was OK.

Paul

3 weeks ago

The updated migrate.php isn't yet available it seems, but looking at last night's PHP error log I found:

PHP
[30-Jul-2026 21:59:58 UTC] PHP Fatal error:  Uncaught RuntimeException: Failed to save file D:/WebData/pwhodges.uk/cache/compiled/blueprints/master-pwhodges.uk.php in D:\WebData\pwhodges.uk\vendor\rockettheme\toolbox\File\src\AbstractFile.php:374
Stack trace:
#0 D:\WebData\pwhodges.uk\vendor\rockettheme\toolbox\File\src\PhpFile.php(46): RocketTheme\Toolbox\File\AbstractFile->save(Array)
#1 D:\WebData\pwhodges.uk\system\src\Grav\Common\Config\CompiledBase.php(255): RocketTheme\Toolbox\File\PhpFile->save(Array)
#2 D:\WebData\pwhodges.uk\system\src\Grav\Common\Config\CompiledBase.php(113): Grav\Common\Config\CompiledBase->saveCompiledFile('D:/WebData/pwho...')
#3 D:\WebData\pwhodges.uk\system\src\Grav\Common\Service\ConfigServiceProvider.php(106): Grav\Common\Config\CompiledBase->load()
#4 D:\WebData\pwhodges.uk\system\src\Grav\Common\Service\ConfigServiceProvider.php(46): Grav\Common\Service\ConfigServiceProvider::blueprints(Object(Grav\Common\Grav))
#5 D:\WebData\pwhodges.uk\vendor\pimple\pimple\src\Pimple\Container.php(122): Grav\Common\Service\ConfigSe in D:\WebData\pwhodges.uk\vendor\rockettheme\toolbox\File\src\AbstractFile.php on line 374

I'm guessing it's maybe a permissions issue, but being Windows that surprises me.

Paul

3 weeks ago

Hang on - is the error in a theme file? I've tried this on two sites, one using Afterburner2 v1.8.1 and the other using Editorial v4.1.0 .

I also have this error from migrate.php:

TXT
[30-Jul-2026 22:04:38 UTC] PHP Parse error:  syntax error, unexpected 'o777' (T_STRING) in D:\WebData\pwhodges.uk\migrate.php on line 523

I guess that's because I'm still on PHP 7.4 here (I have a forum that required it, though a recent - and final - update to now supports 8.0 max). As I now see (I missed it before) Grav 2 requires PHP 8.3 minimum - maybe an early check for compatibility might be prudent!

I guess I need to run two PHP versions in parallel, which will likely require tweaking my php-fpm script.

Paul

last edited 07/31/26 by Paul Hodges
3 weeks ago

You have to be on PHP 8.3, so could be that.

3 weeks ago

If only you were on a mac or linux, you could use Reeve.. a rust-based TUI i built to let you run apache/ngins/caddy all simultaneously and also switching between php versions in virtual hosts, servers, etc. Full and complete control! https://github.com/yetidevworks/reeve

3 weeks ago

I'll just run multiple invocations of my windows php-fpm exposing different php versions on a different block of ports. That will be working in a few minutes - after a break for supper.

Reeve looks fun - but it's not something I'd want to spend time on. I'm long retired, and try to simplify things in my home network rather than adding too much!

Paul

3 weeks ago

Use docker. its easier to maintain and migrate, ultra portable, you can even move pc or vps, as long you keep the docker-compose file, without lengthy setup. You just need a few adjustment on your cli habit.

it has a low learning curve and i'd be happy to guide you, if you wanna try.

last edited 07/31/26 by milkboy
6 days ago

My problems above turned out to be a subtle PHP configuration issue; I was unable to locate the exact cause, but reconfiguring PHP 8.5 from scratch cured it.

I have now been able to run the migration wizard, but I end up with no admin plugin - neither old nor new. If I try to download Admin2 from Git it says: 429 two many requests.

What now?

Paul

6 days ago

The problem is Github is down across multiple verticals... this has broken Grav's GPM so you can't download anything. https://www.githubstatus.com/

last edited 08/17/26 by Andy Miller
6 days ago

OK, got it. So when that's fixed, should I just rerun the migration (everything else is fine) or install admin2 manually?

Paul

6 days ago

rerun the migration, it will automatically disable admin, migrate your users to admin2 compatible, and install admin2 to the /admin route (or your custom path if you have one).

5 days ago

Today I was able to migrate both of my Grav sites without significant hassle. Thanks for your help.

Paul

👍 1
5 days ago

Great news Paul!

Suggested topics

Topic Participants Replies Views Activity
Support · by Lauw, 7 days ago
2 98 6 days ago
Support · by Anna, 2 weeks ago
4 426 1 week ago
Support · by gtx, 4 weeks ago
4 376 3 weeks ago
Support · by Anna, 1 month ago
9 482 3 weeks ago
Support · by TomW, 1 month ago
4 316 4 weeks ago