diff --git a/README.md b/README.md index c7fe48c..8b6e56c 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,11 @@ This **experimental** add-on tries to address that need, although there are a nu 1. The build done using this process uses the technique from [static-php-cli](https://github.com/crazywhalecc/static-php-cli) and full details are available there. It supports all the versions supported in the upstream repository, currently PHP 7.3-8.5. 2. The build does not match the build done using the official DDEV php packages (which actually come from [deb.sury.org](https://deb.sury.org/). -3. It currently does not provide xdebug, see [extension support](https://static-php.dev/en/guide/extension-notes.html). -4. The resultant PHP binaries built here do not have the exact same extensions as the official DDEV PHP binaries. -5. Building the binaries happens in the build phase of `ddev start`, and it takes a long time on the first `ddev start` or whenever you change versions. My tests on Gitpod, with a great internet connection, took about 8-9 minutes. It can be really annoying, and a better way to build would be an improvement. +3. It does not provide Xdebug, so `ddev xdebug` doesn't work. `xhprof` isn't built by default, and `ddev xhprof` hasn't been tested with it. See [extension support](https://static-php.dev/en/guide/extension-notes.html). +4. The resultant PHP binaries built here do not have the exact same extensions as the official DDEV PHP binaries, see [Extensions](#extensions). +5. Building the binaries happens in the build phase of `ddev start`, and it takes a long time on the first `ddev start` or whenever you change versions. The build uses static-php-cli's pre-built libraries where they exist; with the default extensions it took about 9 minutes on an Apple Silicon Mac. Each extension you add makes it longer. 6. If you want to see the build process as it proceeds, you can use `ddev utility rebuild` or `DDEV_VERBOSE=true ddev start`. -7. When you use this add-on, your DDEV `php_version` setting is ignored. +7. When you use this add-on, your DDEV `php_version` setting doesn't choose the PHP binary, but DDEV's `php.ini` and `php-fpm` configuration still come from it. Set `php_version` to the same minor version you build, for example `ddev config --php-version=8.5` for 8.5.12. See [PHP configuration](#php-configuration). 8. To see what's going on during the build, use `ddev utility rebuild -s web --cache` 9. Your mileage may vary. @@ -34,6 +34,37 @@ ddev restart After installation, make sure to commit the `.ddev` directory to version control. +## PHP configuration + +The static PHP binaries use DDEV's `php.ini` for the CLI and for `php-fpm`, so DDEV's settings such as `memory_limit`, upload limits and Mailpit's `sendmail_path` apply as usual. + +Custom settings in `.ddev/php/*.ini` work as with the regular DDEV PHP. Don't put `extension=` lines in them: static PHP can't load shared extensions. Add the extension to `STATIC_PHP_EXTENSIONS` instead. + +Run `ddev php --ini` to see which files are loaded. + +## Extensions + +The default build includes the extensions most projects need, listed under `STATIC_PHP_EXTENSIONS` below. + +These extensions in the regular DDEV PHP aren't built by default, but you can add them to `STATIC_PHP_EXTENSIONS`. Each one adds to the build time: + +`bz2`, `ffi`, `gettext`, `igbinary`, `imagick`, `ldap`, `memcached`, `msgpack`, `readline`, `redis`, `shmop`, `soap`, `sockets`, `sysvmsg`, `sysvsem`, `sysvshm`, `xhprof`, `xsl`, `yaml` + +Setting `STATIC_PHP_EXTENSIONS` replaces the default list, so start from the default and add to it. For example, to add `redis` and `igbinary`: + +```bash +ddev dotenv set .ddev/.env.php-patch-build --static-php-extensions="apcu,bcmath,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,gd,iconv,intl,mbstring,mysqli,openssl,pcntl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,phar,posix,session,simplexml,sodium,sqlite3,tokenizer,xml,xmlreader,xmlwriter,zip,redis,igbinary" +ddev restart +``` + +Run `ddev php -m` to check which extensions are built in. See static-php-cli's [extension list](https://static-php.dev/en/guide/extensions.html) for everything it can build. + +These are not available: + +* `uploadprogress`: not supported by static-php-cli. Applications such as Drupal still work, but don't show upload progress bars. +* `xdebug`: see the caveats above. +* `xmlrpc`: not supported by static-php-cli. + ## Advanced Customization You can choose a different PHP version with: @@ -54,10 +85,10 @@ export DDEV_GITHUB_TOKEN=your_github_token DDEV passes `DDEV_GITHUB_TOKEN`, `GH_TOKEN`, or `GITHUB_TOKEN` to the build as a secret, so the token isn't stored in the image. This requires DDEV newer than v1.25.4; older versions build without a token. -| Variable | Flag | Default | -|-------------------------|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------| -| `STATIC_PHP_EXTENSIONS` | `--static-php-extensions` | `apcu,bcmath,ctype,curl,dom,fileinfo,filter,ftp,gd,mbstring,openssl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,phar,session,simplexml,sqlite3,tokenizer,xml` | -| `STATIC_PHP_VERSION` | `--static-php-version` | required, (not set) | +| Variable | Flag | Default | +|-------------------------|---------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `STATIC_PHP_EXTENSIONS` | `--static-php-extensions` | `apcu,bcmath,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,gd,iconv,intl,mbstring,mysqli,openssl,pcntl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,phar,posix,session,simplexml,sodium,sqlite3,tokenizer,xml,xmlreader,xmlwriter,zip` (`opcache` is added for PHP 8 and later) | +| `STATIC_PHP_VERSION` | `--static-php-version` | required, (not set) | ## Credits diff --git a/docker-compose.php-patch-build.yaml b/docker-compose.php-patch-build.yaml index ae9fc33..89a6cde 100644 --- a/docker-compose.php-patch-build.yaml +++ b/docker-compose.php-patch-build.yaml @@ -5,7 +5,7 @@ services: build: args: # required, comma-separated list of PHP extensions to build - STATIC_PHP_EXTENSIONS: "${STATIC_PHP_EXTENSIONS:-apcu,bcmath,ctype,curl,dom,fileinfo,filter,ftp,gd,mbstring,openssl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,phar,session,simplexml,sqlite3,tokenizer,xml}" + STATIC_PHP_EXTENSIONS: "${STATIC_PHP_EXTENSIONS:-apcu,bcmath,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,gd,iconv,intl,mbstring,mysqli,openssl,pcntl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,phar,posix,session,simplexml,sodium,sqlite3,tokenizer,xml,xmlreader,xmlwriter,zip}" # required, the PHP version to build STATIC_PHP_VERSION: "${STATIC_PHP_VERSION}" x-ddev: diff --git a/tests/test.bats b/tests/test.bats index 36d5109..6ae5928 100644 --- a/tests/test.bats +++ b/tests/test.bats @@ -40,6 +40,9 @@ setup() { export CUSTOM_PHP_MINOR_VERSION="8.3.19" printf "index.php assert_file_exist index.php + printf "ini.php + mkdir -p .ddev/php + printf "upload_max_filesize = 7M\n" >.ddev/php/test.ini } health_checks() { @@ -77,6 +80,25 @@ health_checks() { assert_output --partial "xml" } +# Checks for changes not yet in a release; move into health_checks after the next release +unreleased_checks() { + # DDEV's php.ini and .ddev/php are used by the CLI and php-fpm + run ddev php ini.php + assert_success + assert_output "-1 7M 1" + + run curl -sf https://${PROJNAME}.ddev.site/ini.php + assert_success + assert_output "1024M 7M 1" + + run ddev php -m + assert_success + refute_output --partial "Warning" + for ext in apcu bcmath calendar ctype curl dom exif fileinfo filter ftp gd iconv intl mbstring mysqli openssl pcntl pdo_mysql pdo_pgsql pdo_sqlite posix session sodium sqlite3 tokenizer xml xmlreader xmlwriter zip "Zend OPcache"; do + assert_line --regexp "^${ext}[[:space:]]*$" + done +} + teardown() { set -eu -o pipefail ddev delete -Oy "${PROJNAME}" >/dev/null 2>&1 @@ -101,6 +123,7 @@ teardown() { run ddev restart -y assert_success health_checks + unreleased_checks } # bats test_tags=release diff --git a/web-build/Dockerfile.php-patch-build b/web-build/Dockerfile.php-patch-build index 25f8a24..8f310fc 100644 --- a/web-build/Dockerfile.php-patch-build +++ b/web-build/Dockerfile.php-patch-build @@ -33,7 +33,7 @@ rm -rf source/* buildroot/* # Retry because GitHub API release lookups fail intermittently; already-downloaded sources are skipped for attempt in 1 2 3; do - if bin/spc download --for-extensions="${STATIC_PHP_EXTENSIONS}" -U "php-src:https://www.php.net/distributions/php-${STATIC_PHP_VERSION}.tar.gz"; then + if bin/spc download --prefer-pre-built --for-extensions="${STATIC_PHP_EXTENSIONS}" -U "php-src:https://www.php.net/distributions/php-${STATIC_PHP_VERSION}.tar.gz"; then break fi if [ "${attempt}" -eq 3 ]; then @@ -47,7 +47,8 @@ done # opcache would normally be here but build fails: https://github.com/crazywhalecc/static-php-cli/issues/192 if [[ ${STATIC_PHP_VERSION} =~ ^[89] ]]; then export STATIC_PHP_EXTENSIONS="${STATIC_PHP_EXTENSIONS},opcache"; fi -bin/spc build "${STATIC_PHP_EXTENSIONS}" --build-cli --build-fpm +# Scan our own conf.d and the project's .ddev/php directory for additional ini files +bin/spc build "${STATIC_PHP_EXTENSIONS}" --build-cli --build-fpm --with-config-file-scan-dir=/usr/local/etc/php/conf.d:/mnt/ddev_config/php chown -R "${uid}:${gid}" /usr/local/src/static-php-cli EOF @@ -55,5 +56,12 @@ EOF # Set up symlinks to make the new PHP version the default php and php-fpm RUN ln -sf /usr/local/src/static-php-cli/buildroot/bin/php /usr/bin/php${DDEV_PHP_VERSION} && \ ln -sf /usr/local/src/static-php-cli/buildroot/bin/php-fpm /usr/sbin/php-fpm${DDEV_PHP_VERSION} && \ - ln -sf /etc/php/${STATIC_PHP_VERSION%.*}/cli/php.ini /etc/php.ini && \ - ln -sf /etc/php/${STATIC_PHP_VERSION%.*}/fpm/php-fpm.conf /etc/php-fpm.conf + ln -sf /etc/php/${DDEV_PHP_VERSION}/fpm/php-fpm.conf /etc/php-fpm.conf + +# Use DDEV's php.ini for each SAPI; static PHP reads php-.ini from its config path before php.ini. +# DDEV's conf.d files can't be used because static PHP can't load shared extensions, +# so carry over the one setting they add +RUN mkdir -p /usr/local/etc/php/conf.d && \ + ln -sf /etc/php/${DDEV_PHP_VERSION}/cli/php.ini /usr/local/etc/php/php-cli.ini && \ + ln -sf /etc/php/${DDEV_PHP_VERSION}/fpm/php.ini /usr/local/etc/php/php-fpm-fcgi.ini && \ + printf 'zend.assertions = 1\n' > /usr/local/etc/php/conf.d/20-assert.ini