Search code examples
symfonycloud-foundryswisscomdev

How to use/enable PHP extensions for CLI on swisscomdev/cloudfoundry php_buildback?


** EDIT **

For several cases we need to call Symfony commands on a deployed CloudFoundry app. Symfony commands are php scripts which are called with the PHP CLI.

One example is bin/console doctrine:schema:update (but could be user generation, cache clearing etc.)

So for our app we need both, fpm and cli enabled. This is done with:

  "PHP_MODULES": [
"fpm",
"cli"]

in options.json.

After connecting to the app with cf ssh I change to app directory and I call php/bin/php doctrine:schema:update this results in a ClassNotFound: PDO issue.

During staging these commands are called successfully.

I checked that for PHP CLI the PDO extension is not available (by checking php -i) although I have mentioned it in options.json.

"PHP_EXTENSIONS": [
 ...
 "pdo",
 "pdo_mysql",
 ...]

How to enable extensions for CLI and FPM on one app? And is it theoretically possible to have different extensions for CLI and FPM and as well different user-php.ini s to fully/particularly override php.ini of CLI and FPM?


Solution

  • So for our app we need both, fpm and cli enabled. This is done with:

    "PHP_MODULES": [ "fpm", "cli"]

    in options.json.

    This is something that we should probably clean up in the build pack. I do not believe it's (PHP_MODULES) actually used any more.

    Maybe a year or more ago, the build pack switched how it downloads PHP. It would previously download individual components modules & extensions. Now it just downloads everything at once. This actually ends up being faster since it's one larger download vs many smaller downloads, and bandwidth is generally very fast for build pack downloads.

    Worth mentioning that while PHP_EXTENSIONS no longer triggers what to download it is still used in terms of what extensions get enabled in php.ini. Thus you still need to set that or indicate extensions through composer.

    After connecting to the app with cf ssh

    I believe that this is the issue. You need to source the build pack env variables so that the env is configured properly.

    Ex:

    vcap@359b74ff-686c-494e-4a1e-46a9c420f262:~$ php
    bash: php: command not found
    
    vcap@359b74ff-686c-494e-4a1e-46a9c420f262:~$ HOME=$HOME/app source app/.profile.d/bp_env_vars.sh
    vcap@359b74ff-686c-494e-4a1e-46a9c420f262:~$ php -v
    PHP 5.6.26 (cli) (built: Oct 28 2016 22:24:22)
    Copyright (c) 1997-2016 The PHP Group
    Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    

    Staging does this automatically as does runtime for your app. Unfortunately cf ssh does not.

    UPDATE:

    A slightly easier way to do this is to run cf ssh myapp -t -c "/tmp/lifecycle/launcher /home/vcap/app bash ''". This will open a bash shell and it lets the lifecycle launcher handle sourcing & setting up the environment.

    And is it theoretically possible to have different extensions for CLI and FPM and as well different user-php.ini s to fully/particularly override php.ini of CLI and FPM?

    Sure. By default, we download and install all extensions. Thus you just need a different php.ini (or some other setting to enable that extension) in which you enable your alternate set of extensions.

    When you cf ssh into the container, you could copy the existing php.ini somewhere else and edit it for your CLI needs. Then reference that php-alt.ini when you run your CLI commands.