Journal

FrankenPHP en conteneur : image officielle et mode worker

Journal du lundi 24 août 2026, généré le 24 août à 09:55

Ce que FrankenPHP change dans un conteneur

FrankenPHP est un serveur d'application écrit en Go qui embarque Caddy et le moteur PHP dans un seul binaire. Contrairement au duo classique nginx + php-fpm, il n'y a plus deux processus à orchestrer ni de socket FastCGI à configurer : un seul conteneur suffit, ce qui simplifie nettement le Dockerfile et le déploiement.

Image de base

L'image officielle dunglas/frankenphp fournit déjà PHP compilé avec les extensions courantes et Caddy intégré. Un Dockerfile minimal pour une application Symfony ou Laravel ressemble à ceci :

FROM dunglas/frankenphp:1-php8.3

WORKDIR /app

RUN install-php-extensions \
    pdo_pgsql \
    opcache \
    zip \
    intl

COPY . /app
COPY frankenphp/Caddyfile /etc/caddy/Caddyfile

RUN composer install --no-dev --optimize-autoloader

Le script install-php-extensions, préinstallé dans l'image, évite de recompiler PHP à la main.

Mode worker : le vrai gain de performance

Le mode classique (vanilla) réexécute le framework à chaque requête, comme avec php-fpm. Le mode worker garde l'application en mémoire entre les requêtes, à la manière d'un runtime Node.js ou de Swoole, ce qui réduit fortement la latence sur les frameworks lourds. Il s'active dans le Caddyfile :

{
    frankenphp {
        worker /app/public/index.php
        num_threads 4
    }
}

:80 {
    root * /app/public
    php_server
}

Attention : en mode worker, l'état global n'est plus réinitialisé automatiquement entre les requêtes. Il faut que le framework gère lui-même le reset du conteneur de services (Symfony le fait nativement depuis la 6.3 via le composant runtime, Laravel via Octane).

Variables d'environnement utiles

  • FRANKENPHP_CONFIG — injecte des directives Caddyfile directement depuis l'environnement, pratique pour un déploiement sans fichier de config versionné.
  • SERVER_NAME — définit le nom d'hôte écouté par Caddy, y compris pour l'obtention automatique de certificats TLS via Let's Encrypt.
  • CADDY_GLOBAL_OPTIONS — ajuste des options globales comme la désactivation d'auto-HTTPS en environnement de dev.

Points de vigilance

  • Le mode worker complique le débogage : une fuite mémoire ou une variable statique mal réinitialisée persiste entre requêtes.
  • Les extensions PHP compilées statiquement dans l'image ne peuvent pas être ajoutées à chaud ; toute extension supplémentaire nécessite un rebuild.
  • Pour le multi-stage, séparez la compilation des assets front (Node) de l'étape FrankenPHP finale afin de garder l'image de production légère.