How to bootstrap Kirby in a given environment from CLI script

How can we bootstrap $kirby with a given environment from a CLI script?

I’ld like to run a PHP script, from a cron job, that bootstraps Kirby and does some things.
One of those things is it needs to flush the pages cache when it’s done. Right now, that doesn’t work because it tries to find the pages cache in the _ folder. I assume that’s because it’s ran from a CLI script and Kirby does not attach the environment I’ld like it to use internally.

I tried setting the url parameter in the config.env.php file, and have setup a global config.php file where I added * as url parameter. Now how can I instantiate $kirby = new Kirby($options); to the given environment I’ld like to run it from?

Another thing is read options set in the environmental config file. So I’ld need to be able to make Kirby believe it’s in a given environment.

Thx!

I do not know if I understand correct, but you just need to require the bootstrap.php from the given Kirby installation. With the following script, I am creating an admin user in a given Kirby installation from the commandline:

<?php
// createUser.php to create a kirby panel admin user
// Usage: php createUser.php DOCROOT EMAIL NAME LANG PASSWORD
// Example: php createUser.php '/srv/www/vhost/kirby-test/htdocs' 'adspectus@fastmail.com' 'Uwe Gehring' 'en' 'secret'

require $argv[1] . '/kirby/bootstrap.php';

$kirby = new Kirby([ 'roots' => [ 'index' => $argv[1] ] ]);

// authenticate as almighty
$kirby->impersonate('kirby');

// create new K3 user account
$kirby->users()->create(['role' => 'admin','email' => $argv[2],'name' => $argv[3],'language' => $argv[4],'password' => $argv[5]]);

?>

The script is part of my kirbytools package which you can find here, if you need more background:

I am bootstrapping Kirby as you said. But, it’s not loading my config.my-domain.tld.php file where I’ve stated the url option to be used. Nor does it take the pages cache option that is configured there. When I var_dump $kirby->cache('pages') from the script it returns the null cache. Also when doing things in plugin caches they are added to the cache/_/ folder instead of cache/my-domain.tld/, which makes me conclude that Kirby is not using the wanted environment my-domain.tld.

I’m pretty sure this question has come up before, but for the life of me I cannot remember in what context and I cannot find anything here via search

Wondering if the Environment class would be useful in this context? Environment | Kirby CMS

Haha, it was you on Discord: Discord

@texnixe , hi :slight_smile:

I’ve found this: Flush pages cache via cli - wrong root which pointed me to the url option. But alas, that doesn’t work when I cannot swith to the right environment…

Ah yes. Then I worked around it, but now I can’t find a way without hard-coding in paths which I really do not want to do considering I have different environments.

It keeps coming back. I’ld love a solution for this!

@texnixe ; some more findings, but first some more background:

I have several environments, lets call them a.tld, b.tld, c.tld for brevity, and each of them has their own config file. So config folder looks like this:

  • config.php
  • config.a.tld.php
  • config.b.tld.php
  • config.c.tld.php

In each of them I have configured the url parameter with their tld.
In config.php, I have configured url: '*'; to allow all (for testing this). This is required according to the docs (it’s potentially dangerous, but I don’t really get why).

When I run a PHP script that bootstraps Kirby over CLI, it only reads the global config.php, where the wildcard is set on the url option… I think it’s because of environment “sniffing”. But this is not what I want, since “*” is not even an environment in my setup; it’s the global config where all shared options live, and adding an url option there that lists all potential options is then a requirement.

During the Kirby bootstrap in the script, I’ld like to be able to “pick” the env (e.g. a.tld) it should merge onto the global config.php to have all env specific options available there, and to work with the right folders in the cache folder.

FYI: I also tried adding another “layer” with real .env files, but I cannot use the env() helper in a closure for the url option in the config. Kirby throws an error Kirby\Http\Environment::detectAllowed(): Argument #1 ($allowed) must be of type array|string, Closure given.

Edit: Do you know how the kirby-cli works with environments? (I’m not a kirby-cli user, but if they solved it there, I could get some clues?)

in the index php if a param is provided via cli (like @Adspectus did) i would overwrite the $_SERVER['SERVER_NAME'] with your intended config (a.tdl, …) before you init kirby. that might work.

1 Like

Thanks for chiming in @bnomei :pray:.

I got it working with feeding $_SERVER['SERVER_NAME'] the url from the .env file.

First of all: Thank you to all previous posters, without you, I would have really been stuck on this.

I would just like to add some detail here, as I came across the same problem, that kirby()->cache('pages')->flush() did not work in my code and it took me quite some time to figure it out, even after reading this post the above related post:

As mentioned in the other post, adding the url option does make kirby()->cache('pages')->flush() work. But if you have a multi-environment setup, like bvdputte wrote above

and try to bootstrap from a CLI script, it throws an error.

As I did not understand how to achieve what bnomei and bvdputte wrote in the two posts above this one, I tried using env.php to override the url in the config, as is stated in kirby docs here.

So, in short, my solution is (examples from kirby docs):

  1. Specifiy an allowlist of domains in the general config.php like so
return [
  'url' => [
    'https://example.com',
    'https://staging.example.com',
    'http://localhost'
  ]
];
  1. Override url in production and every environment you need kirby()->cache('pages')->flush() to work in file env.php like so:
return [
  'url' => 'https://example.com'
];

@luca , add this at the beginning of your CLI script: $_SERVER['SERVER_NAME'] = "https://example.com";. Then your script tricks Kirby into thinking the request comes from example.com and it’ll load that config.

2 Likes

Thank you, @bvdputte . Learning new things every day with Kirby :slightly_smiling_face:

1 Like