Using FrankenPHP with DDEV

Introduction
The PHP ecosystem is changing fast, with tools like FrankenPHP improving both performance and developer experience.
FrankenPHP is now officially supported by The PHP Foundation.
This guide explains two ways to integrate FrankenPHP, based on my experience.
You can either run FrankenPHP as a separate service (lets you install extra PHP extensions) or inside DDEV’s web
container (uses a static binary without support for extra extensions).
Generic web server
This blog shows examples of the recently added DDEV’s generic web server, which supports flexible configurations. It allows you to use any custom web server you want, including Node.js, Python, Ruby, etc.
DDEV FrankenPHP Add-on
I created the stasadev/ddev-frankenphp add-on to experiment with FrankenPHP as a separate service with some additional features:
- Ability to install PHP extensions (Redis, Xdebug, SPX, etc.)
- Better resource isolation
⚙️ Installation:
ddev config --webserver-type=generic
ddev add-on get stasadev/ddev-frankenphp
ddev restart
To add PHP extensions (see supported extensions here):
ddev dotenv set .ddev/.env.frankenphp --frankenphp-php-extensions="redis pdo_mysql"
ddev add-on get stasadev/ddev-frankenphp
ddev stop && ddev debug rebuild -s frankenphp && ddev start
⚠️ Limitations:
- Standard Linux and DDEV tools are installed in the
web
container, not in thefrankenphp
container. - See the add-on README for adding Xdebug (
ddev xdebug
does not work here). - Enabling or disabling Xdebug requires rebuilding the
frankenphp
container. ddev launch
does not work because the web server runs in a different container.
If you want to suggest some feature or found a bug, feel free to open an issue.
Running FrankenPHP in the Web Container
Alternatively, FrankenPHP can be run inside the web
container. This example from the DDEV quickstart shows a setup (for a Drupal 11 project) where FrankenPHP is added as an extra daemon.
⚙️ Installation:
export FRANKENPHP_SITENAME=my-frankenphp-site
mkdir ${FRANKENPHP_SITENAME} && cd ${FRANKENPHP_SITENAME}
ddev config --project-type=drupal11 --webserver-type=generic --docroot=web --php-version=8.4
ddev start
cat <<'EOF' > .ddev/config.frankenphp.yaml
web_extra_daemons:
- name: "frankenphp"
command: "frankenphp php-server --listen=0.0.0.0:80 --root=\"/var/www/html/${DDEV_DOCROOT:-}\" -v -a"
directory: /var/www/html
web_extra_exposed_ports:
- name: "frankenphp"
container_port: 80
http_port: 80
https_port: 443
EOF
cat <<'DOCKERFILEEND' >.ddev/web-build/Dockerfile.frankenphp
RUN curl -s https://frankenphp.dev/install.sh | sh
RUN mv frankenphp /usr/local/bin/
RUN mkdir -p /usr/local/etc && ln -s /etc/php/${DDEV_PHP_VERSION}/fpm /usr/local/etc/php
DOCKERFILEEND
ddev composer create-project drupal/recommended-project
ddev composer require drush/drush
ddev restart
ddev drush site:install demo_umami --account-name=admin --account-pass=admin -y
ddev launch
# or automatically log in with
ddev launch $(ddev drush uli)
⚠️ Limitations:
- It’s not possible to install additional PHP extensions (requires ZTS build).
- Limited debugging capabilities,
ddev xdebug
doesn’t work.
Resources
- FrankenPHP documentation
- DDEV’s generic web server
- FrankenPHP add-on
- FrankenPHP quickstart
- Hola FrankenPHP! Laravel Octane Servers Comparison: Pushing the Boundaries of Performance
Benchmarking
Using ddev-frankenphp-benchmark, I compared three setups:
nginx-fpm
: DDEV’snginx-fpm
web server withphp-fpm
generic-web
: DDEV’sgeneric
web server with FrankenPHP inside theweb
container (static binary)generic-addon
: DDEV’sgeneric
web server with FrankenPHP inside thefrankenphp
container (withpdo_mysql
extension)
Summary:
- All configurations delivered comparable and adequate performance.
- FrankenPHP is a win where there is an upstream hosting environment using FrankenPHP.
- Benchmarks used default DDEV settings, not production-optimized configurations.
- Laravel Octane (FrankenPHP worker mode) was not used and could yield better results.
- CPU and memory usage were not measured.
Benchmarking Results
Software:
DDEV: v1.24.6
Mutagen: disabled
PHP: v8.4
Laravel: v12.19.3
FrankenPHP: v1.7.0
Docker Engine: v28.3.0
Operating System: Manjaro Linux AMD64
Kernel Version: 6.12.35-1-MANJARO
Hardware:
Intel i7 8750H (6 Core/12 Thread, 2.2 Ghz, Turbo 4.1 Ghz)
32 GB DDR4 2667 Mhz
Samsung 870 Evo SSD (530w/560r MB/s)
If you find DDEV (and its add-ons like FrankenPHP) useful, consider supporting its development. Thank you!