Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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:
Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion docker-compose.php-patch-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
23 changes: 23 additions & 0 deletions tests/test.bats
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ setup() {
export CUSTOM_PHP_MINOR_VERSION="8.3.19"
printf "<?php\necho phpversion();\n" >index.php
assert_file_exist index.php
printf "<?php\necho ini_get('memory_limit'), ' ', ini_get('upload_max_filesize'), ' ', ini_get('zend.assertions');\n" >ini.php
mkdir -p .ddev/php
printf "upload_max_filesize = 7M\n" >.ddev/php/test.ini
}

health_checks() {
Expand Down Expand Up @@ -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
Expand All @@ -101,6 +123,7 @@ teardown() {
run ddev restart -y
assert_success
health_checks
unreleased_checks
}

# bats test_tags=release
Expand Down
16 changes: 12 additions & 4 deletions web-build/Dockerfile.php-patch-build
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -47,13 +47,21 @@ 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

# 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-<sapi>.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
Loading