Skip to content
Draft
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/img/blog/2025/07/frankenphp-request-per-second.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/img/blog/2025/07/frankenphp-requests.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/img/blog/2025/07/frankenphp-transfer-per-second.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
96 changes: 18 additions & 78 deletions src/content/blog/using-frankenphp-with-ddev.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: "Using FrankenPHP with DDEV"
pubDate: 2025-07-03
modifiedDate: 2025-11-27
modifiedComment: The FrankenPHP add-on is now official.
modifiedDate: 2025-12-30
modifiedComment: Update FrankenPHP add-on instructions, remove deprecated content, update benchmark results.
summary: Learn how to use FrankenPHP with DDEV through the official add-on or Debian packages. Includes installation steps, features, and performance benchmarks.
author: Stas Zhuk
featureImage:
Expand All @@ -20,16 +20,13 @@ The PHP ecosystem is changing fast, with tools like [FrankenPHP](https://franken

FrankenPHP is now [officially supported](https://thephp.foundation/blog/2025/05/15/frankenphp/) by The PHP Foundation.

This guide explains two ways to integrate FrankenPHP with DDEV:

1. **Official DDEV add-on** (recommended): Run FrankenPHP as a separate service with full PHP extension support and flexibility
2. **Debian packages**: Install FrankenPHP directly in the web container (PHP 8.4 only, limited features)
This guide explains how FrankenPHP can be used with DDEV using [ddev/ddev-frankenphp](https://github.com/ddev/ddev-frankenphp) add-on.

### Generic web server

This blog shows examples of the recently added [DDEV's generic web server](https://docs.ddev.com/en/stable/users/extend/customization-extendibility/#using-nodejs-as-ddevs-primary-web-server), which supports flexible configurations. It allows you to use any custom web server you want, including Node.js, Python, Ruby, etc.
This blog shows an example of the recently added [DDEV's generic web server](https://docs.ddev.com/en/stable/users/extend/customization-extendibility/#using-nodejs-as-ddevs-primary-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 (Recommended)
## DDEV FrankenPHP Add-on

The [ddev/ddev-frankenphp](https://github.com/ddev/ddev-frankenphp) add-on is now officially maintained by the DDEV team! It has matured to production-ready status with full feature support.

Expand All @@ -40,11 +37,12 @@ ddev add-on get ddev/ddev-frankenphp
ddev restart
```

To add PHP extensions (see supported extensions [here](https://github.com/mlocati/docker-php-extension-installer?tab=readme-ov-file#supported-php-extensions)):
Install pre-packaged extensions using the `php-zts-` prefix (see [supported extensions](https://pkg.henderkes.com/84/php-zts/packages?type=debian)):

```bash
ddev dotenv set .ddev/.env.web --frankenphp-custom-extensions="redis memcached"
ddev stop && ddev debug rebuild && ddev start
# install mongodb and sqlsrv extensions
ddev config --webimage-extra-packages="php-zts-mongodb,php-zts-sqlsrv"
ddev restart
```

### ✨ Features:
Expand All @@ -53,83 +51,25 @@ ddev stop && ddev debug rebuild && ddev start
- Install any PHP extension (Redis, Xdebug, Memcached, etc.)
- Custom FrankenPHP options supported
- Worker mode supported for maximum performance
- Full debugging support: [`ddev xdebug`](https://docs.ddev.com/en/stable/users/usage/commands/#xdebug), [`ddev xhprof`](https://docs.ddev.com/en/stable/users/usage/commands/#xhprof), [`ddev xhgui`](https://docs.ddev.com/en/stable/users/usage/commands/#xhgui)

Note: Initial `ddev start` takes longer due to manual extension compilation.
- Full debugging support: [`ddev blackfire`](https://docs.ddev.com/en/stable/users/usage/commands/#blackfire), [`ddev xdebug`](https://docs.ddev.com/en/stable/users/usage/commands/#xdebug), [`ddev xhprof`](https://docs.ddev.com/en/stable/users/usage/commands/#xhprof), [`ddev xhgui`](https://docs.ddev.com/en/stable/users/usage/commands/#xhgui)

If you want to suggest some feature or found a bug, feel free to [open an issue](https://github.com/ddev/ddev-frankenphp/issues).

## Alternative: FrankenPHP via Debian Packages

FrankenPHP can also be installed directly in the web container using Debian packages. This example from the [DDEV quickstart](https://docs.ddev.com/en/stable/users/quickstart/#generic-frankenphp) shows a setup for a Drupal 11 project where FrankenPHP runs as an extra daemon.

### ⚙️ Installation:

```bash
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 -fsSL https://key.henderkes.com/static-php.gpg -o /usr/share/keyrings/static-php.gpg && \
echo "deb [signed-by=/usr/share/keyrings/static-php.gpg] https://deb.henderkes.com/ stable main" > /etc/apt/sources.list.d/static-php.list
# Install FrankenPHP and extensions, see https://frankenphp.dev/docs/#deb-packages for details.
# You can find the list of available extensions at https://deb.henderkes.com/pool/main/p/
RUN (apt-get update || true) && DEBIAN_FRONTEND=noninteractive apt-get install -y -o Dpkg::Options::="--force-confnew" --no-install-recommends --no-install-suggests \
frankenphp \
php-zts-cli \
php-zts-gd \
php-zts-pdo-mysql
# Make sure that 'php' command uses the ZTS version of PHP
# and that the php.ini in use by FrankenPHP is the one from DDEV.
RUN ln -sf /usr/bin/php-zts /usr/local/bin/php && \
ln -sf /etc/php/${DDEV_PHP_VERSION}/fpm/php.ini /etc/php-zts/php.ini
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:

- PHP 8.4 only (no version flexibility)
- Cannot customize FrankenPHP options
- Worker mode not supported
- No debugging support (`ddev xdebug`, `ddev xhprof`, `ddev xhgui` do not work)

## Resources

- [FrankenPHP documentation](https://frankenphp.dev/docs/)
- [DDEV's generic web server](https://docs.ddev.com/en/stable/users/extend/customization-extendibility/#using-nodejs-as-ddevs-primary-web-server)
- [FrankenPHP add-on](https://github.com/ddev/ddev-frankenphp)
- [FrankenPHP quickstart](https://docs.ddev.com/en/stable/users/quickstart/#generic-frankenphp)
- [FrankenPHP Static PHP Package Repository](https://debs.henderkes.com/)
- [Hola FrankenPHP! Laravel Octane Servers Comparison: Pushing the Boundaries of Performance](https://medium.com/beyn-technology/hola-frankenphp-laravel-octane-servers-comparison-pushing-the-boundaries-of-performance-d3e7ad8e652c)

## Benchmarking

Using [ddev-frankenphp-benchmark](https://github.com/stasadev/ddev-frankenphp-benchmark), I compared three setups:

- `nginx-fpm`: DDEV's `nginx-fpm` web server with `php-fpm`
- `generic-web`: DDEV's `generic` web server with FrankenPHP inside the `web` container (static binary)
- `generic-addon`: DDEV's `generic` web server with FrankenPHP inside the `frankenphp` container (with `pdo_mysql` extension)
- `frankenphp`: DDEV's `generic` web server with `frankenphp`
- `apache-fpm`: DDEV's `apache-fpm` web server with `php-fpm`

Summary:

Expand All @@ -142,14 +82,14 @@ Summary:
### Benchmarking Results

<b>Software:</b><br>
DDEV: v1.24.6<br>
DDEV: v1.24.10<br>
Mutagen: disabled<br>
PHP: v8.4<br>
Laravel: v12.19.3<br>
FrankenPHP: v1.7.0<br>
Docker Engine: v28.3.0<br>
Laravel: v12.44.0<br>
FrankenPHP: v1.11.1<br>
Docker Engine: v29.1.3<br>
Operating System: Manjaro Linux AMD64<br>
Kernel Version: 6.12.35-1-MANJARO
Kernel Version: 6.12.63-1-MANJARO

<b>Hardware:</b><br>
Intel i7 8750H (6 Core/12 Thread, 2.2 Ghz, Turbo 4.1 Ghz)<br>
Expand Down
Loading