paketo-buildpacks / php

A Cloud Native Buildpack for PHP
Apache License 2.0
25 stars 9 forks source link

How to Add PHP Extension and documentation suggestion #355

Open FelipoAntonoff opened 3 years ago

FelipoAntonoff commented 3 years ago

Hello, I would like to know how to add new PHP extensions, such as Phalcon, Swoole or some other extension not included in Buildpack?

I would also like to suggest more details like the PHP versions supported in the documentation, I was able to see it in Releases and which extensions are included natively, I missed the documentation of these details and also examples of more complete uses such as adding a new extension, adding SSL through Let's Encrypt and Database like MySQL / Mariadb and the like.

The idealization of this project is very good, if it gets a little more complete, the documentation should make it even easier to use, thanks.

FelipoAntonoff commented 3 years ago

I did a test using the example: https://github.com/paketo-buildpacks/php-composer/tree/main/integration/testdata/composer_app_extensions

Run

pack build php-composer --buildpack gcr.io/paketo-buildpacks/php \
  --builder paketobuildpacks/builder:full

docker run -d -p 8080:8080 -e PORT=8080 php-composer
curl http://localhost:8080/extensions.php

Returns installed extensions

I changed composer.json a little to try new extensions:

{
    "require": {
        "monolog/monolog": "1.0.*",
        "php": ">=7.1",
        "ext-zip": "*",
        "ext-phpredis": "*",
        "ext-openssl": "*",
        "ext-mencached": "*",
        "ext-phalcon": "*",
        "ext-pdo": "*",
        "ext-pdo_mysql": "*",
        "ext-gd": "*",
        "ext-fileinfo": "*",
        "ext-mysqli": "*",
        "ext-mbstring": "*"
    },
    "scripts": {
        "post-install-cmd": [
            "php -r 'foreach (get_loaded_extensions() as $ext) { print(\"PostInstall [$ext]\\n\"); }'"
        ]
    }
}

Result final:

Core
date
libxml
pcre
sqlite3
bcmath
calendar
ctype
dom
filter
hash
iconv
intl
json
SPL
posix
Reflection
session
SimpleXML
standard
Phar
tokenizer
xml
xmlreader
xmlwriter
mysqlnd
cli_server
fileinfo
gd
mbstring
mysqli
PDO
pdo_mysql
zip

Through the composer it was possible to add new extensions, but some were not added because it is more complex like Phalcon, Mencached and Redis.

Perhaps in these cases some way to pass the path of the .so file generated from the extension to part, example of Redis: https://github.com/phpredis/phpredis/blob/develop/INSTALL.markdown

And from Phalcon: https://docs.phalcon.io/3.4/en/installation#compile-phalcon

dmikusa commented 3 years ago

There are a few different things here I want to mention:

  1. By default, the buildpacks will install all of the extensions, but only a minimal set of extensions are enabled in PHP's configuration. This is to keep the memory footprint of PHP as low as possible. i.e. don't include things users won't need.

  2. The versions of PHP that we bundle include a pretty large set of extensions. Due to #1, you probably just need to enable the extension that you want. You can look at the v2 PHP buildpack to see what extensions are bundled. The PHP binaries used are the same for both the v2 and v3 buildpacks. +100 on including that information in the release notes for this repo as well.

  3. There are two ways of turning on extensions: Composer, like you found, and a custom ini snippet. See instructions here for how to include ini snippets (the ini snippet can include any valid PHP ini config, including enabling extensions).

  4. The set of extensions available in our binary distributions varies by version of PHP. In a perfect world, they would all be the same, but some PHP extensions are not compatible with particular versions or fail in our builds for various reasons. Usually, as a version of PHP has been around longer, it gets more extensions since issues get resolved.

  5. If there is an extension that you want to use which is not in the distribution of PHP then it would need to be added to the compilation process. I would defer to @thitch97 or @martyspiewak on this as I'm not 100% sure offhand where that repo resides.

arjun024 commented 3 years ago

See the documentation to add custom .ini files: https://paketo.io/docs/buildpacks/language-family-buildpacks/php/#configuring-custom-ini-files. An example is here: https://github.com/paketo-buildpacks/php-web/blob/main/integration/testdata/php_modules/.php.ini.d/snippet.ini

For php versions, you should be able to view the details from the release of the corresponding version of php-dist buildpack packed with this php language-family buildpack. For e.g. https://github.com/paketo-buildpacks/php-dist/releases/tag/v0.2.0 PHP samples are located in https://github.com/paketo-buildpacks/samples/tree/main/php. Feel free to PR in more samples

FelipoAntonoff commented 2 years ago

Hi, thanks for the info.

I will analyze the past information for future use of Paketo in Production. I plan to use it for Opencart, Phalcon and other PHP projects.

enumag commented 2 years ago

There are some PECL extensions I'd like to have available. Namely grpc, amqp, ds, event and eio. 🤔 In this order of importance, grpc being the only critical one.

sophiewigmore commented 2 years ago

@enumag Unfortunately, the only extensions you can add with the buildpacks currently are the ones that come with the distribution of PHP, so if any of those aren't in the list there's no way to add them at the moment. I can file an issue to look into a better way of adding support for other extensions in the future.

For the extensions that do come with PHP, they can be used by adding a composer.json with the extensions listed, or by adding a custom .ini file as mentioned above. I can take an action item to add better documentation around this process.

enumag commented 2 years ago

Yeah all of these are PECL extensions... they aren't too difficult to install though. Just install an appropriate library and run pecl install.

Possible optimization is that for installation dev libraries are necessary but runtime needs just the non dev ones.

sophiewigmore commented 2 years ago

@enumag we support some PECL extensions already, just not all of them

enumag commented 2 years ago

Where can I find the definitions for the already supported pecl extensions? If it's simple enough I might be able to send a PR for those I need.

sophiewigmore commented 2 years ago

@enumag it's pretty complicated how it all works together, as I outlined in https://github.com/paketo-buildpacks/php/issues/529 I want to see if we can find a better way to handle this eventually. I'm not sure if we'd want to add extra extensions here, because then they'd be there for everyone. Anyways, the lists of extensions are defined for each version of PHP: PHP 7 extensions list PHP 7.4 additional extensions PHP 8 extensions list PHP 8.1 additional extensions

enumag commented 2 years ago

https://github.com/cloudfoundry/buildpacks-ci/blob/a72af23c382e7482ed9a23a2655aaf2c5c3a7738/tasks/build-binary-new/php8-base-extensions.yml#L164-L167

@sophiewigmore It seems to refer to some AmqpPeclRecipe... where can I find these recipes?

sophiewigmore commented 2 years ago

https://github.com/cloudfoundry/binary-builder/blob/543c706d05f0245f476f47c7add22fbb35758761/recipe/php_common_recipes.rb#L62-L69 and https://github.com/cloudfoundry/binary-builder/blob/543c706d05f0245f476f47c7add22fbb35758761/recipe/php_common_recipes.rb#L39-L60

enumag commented 2 years ago

@sophiewigmore That... doesn't make sense... amqp extension requires librabbitmq-dev to be installed for pecl install amqp to work and then librabbitmq4 for runtime. I don't see either of these mentioned there. - That is if the image is debian-based, not sure if that's the case.

Also it seems that AmqpPeclRecipe overrides configure_options with the exact same definition as is already in PeclRecipe - likely something left there by accident.