PHP-FPM Image
Kompletter Web-Stack mit separatem PHP-FPM- und Nginx-Image, für Web-Apps, REST-APIs und SPAs. Security-Headers, Gzip-Kompression, Static-Asset-Caching, FPM-Pool-Tuning. Alles per ENV konfigurierbar.
Überblick
Das Projekt liefert zwei zusammengehörige Images: headgent/phpfpm (PHP-FPM mit vollständigem Extension-Stack) und headgent/nginx (vorkonfigurierter Reverse-Proxy mit Security-Hardening). Beide sind Multi-Arch, Multi-Stage und ohne Rebuild über Environment-Variablen konfigurierbar.
GitHub: jardisOps/phpfpm
| Image | Tag-Format | Größe |
|---|---|---|
headgent/phpfpm | 8.2, 8.3, 8.4, latest | ~130 MB |
headgent/nginx | 1.28 | ~25 MB |
| Eigenschaft | Wert |
|---|---|
| PHP-Versionen | 8.2, 8.3, 8.4 |
| Nginx-Version | 1.28 |
| Architekturen | linux/amd64, linux/arm64 |
| Basis | Alpine 3.23 |
Installation
docker pull headgent/phpfpm:8.4
docker pull headgent/nginx:1.28Quick Start
# docker-compose.yml
services:
app:
image: headgent/phpfpm:8.4
volumes:
- ./:/app
environment:
PHP_MEMORY_LIMIT: 256M
XDEBUG_MODE: "off"
FPM_PM_MAX_CHILDREN: 10
webserver:
image: headgent/nginx:1.28
ports:
- "80:80"
environment:
APP_ROOT: /app
DOCUMENT_ROOT: /public
INDEX_FILE: index.php
PHP_PORT: 9000
depends_on:
- appPHP-FPM Image
Extensions
Das PHP-FPM-Image enthält denselben Extension-Stack wie das CLI-Image, mit Ausnahme von pcntl (nicht relevant für FPM-Prozesse):
Datenbank: pdo, pdo_mysql, mysqli, pdo_pgsql Messaging: amqp (2.2.0), rdkafka (6.0.5) Caching: apcu (5.1.28), redis (6.3.0), opcache Web/I/O: curl, soap, sockets, dom, zip Text: mbstring, intl, bcmath Media: gd (FreeType + JPEG), exif Debugging: xdebug (3.5.1), pcov (1.0.12)
PHP-Konfiguration
Identisch zum CLI-Image, mit einem Unterschied:
| Variable | CLI Default | FPM Default |
|---|---|---|
PHP_MAX_EXECUTION_TIME | 0 (unbegrenzt) | 30 (Sekunden) |
XDEBUG_MODE | debug | off |
OPCACHE_VALIDATE_TIMESTAMPS | — | 0 (Produktion) |
OPCACHE_REVALIDATE_FREQ | 2 | 0 (Produktion) |
FPM-Pool-Konfiguration
| Variable | Default | Beschreibung |
|---|---|---|
FPM_PM | dynamic | Prozess-Manager (static, dynamic, ondemand) |
FPM_PM_MAX_CHILDREN | 5 | Max. Worker-Prozesse |
FPM_PM_START_SERVERS | 2 | Initiale Worker |
FPM_PM_MIN_SPARE_SERVERS | 1 | Min. Idle-Worker |
FPM_PM_MAX_SPARE_SERVERS | 3 | Max. Idle-Worker |
FPM_PM_MAX_REQUESTS | 500 | Requests pro Worker vor Restart |
Pool-Tuning für Produktion
Für Produktionslasten: FPM_PM=static mit FPM_PM_MAX_CHILDREN = verfügbarer RAM ÷ ~40 MB pro Worker. Ein Server mit 4 GB RAM → FPM_PM_MAX_CHILDREN=80 (abzüglich OS + Nginx + Redis).
Health Check
Das Image hat einen eingebauten Health Check über den FPM-Ping-Endpoint:
cgi-fcgi -bind -connect 127.0.0.1:9000 /ping → "pong"Status-Endpoint: /status (FPM-Pool-Statistiken).
Nginx Image
Features
- Gzip-Kompression — Level 6, für JS, JSON, XML, CSS, Text, SVG
- Security-Headers — HSTS, CSP, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection
- Static-Asset-Caching — 1 Jahr für CSS, JS, Bilder, Fonts, Icons
- FastCGI-Optimierung — 128k Buffer, 600s Timeout, korrekte PATH_INFO-Behandlung
- Real-IP-Unterstützung — Docker-Netzwerke und Private Networks
- Sicherheit — Blockiert
.htaccess,.svn,.git,.env
Konfiguration
| Variable | Default | Beschreibung |
|---|---|---|
APP_ROOT | /app | Basis-Verzeichnis der Anwendung |
DOCUMENT_ROOT | /public | Relative Document Root |
INDEX_FILE | index.php | Front-Controller |
HOST | localhost | Server-Name |
PHP_PORT | 9000 | PHP-FPM Port |
Die Nginx-Konfiguration wird beim Start via envsubst aus einem Template generiert. Die Variablen werden zur Laufzeit eingesetzt.
Security-Headers
Referrer-Policy: no-referrer-when-downgrade
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'Blockierte Pfade
/.htaccess → 403
/.svn → 403
/.git → 403
/.env → 403Sicherheit
- Non-Root-Execution — beide Images laufen als
appuser(konfigurierbar via PUID/PGID) - Automatische UID/GID-Anpassung — FPM-Image passt sich an den Volume-Owner an
- Kein Xdebug in Produktion — Default
XDEBUG_MODE=off expose_php = Off— PHP-Version wird nicht exponiert- Server-Tokens deaktiviert — Nginx-Version wird nicht exponiert
- Health Check — FPM-Ping auf Port 9000
Makefile
| Target | Beschreibung |
|---|---|
make phpfpm-build | PHP-FPM lokal bauen |
make phpfpm-build-all | Alle PHP-Versionen lokal bauen |
make nginx-build | Nginx lokal bauen |
make build-all | Alle Images lokal bauen |
make phpfpm-push | PHP-FPM multi-arch bauen und pushen |
make phpfpm-push-all | Alle PHP-Versionen multi-arch pushen |
make nginx-push | Nginx multi-arch pushen |
make build-and-push-all | Alles bauen und pushen |
make build-cache-delete | Buildx-Cache löschen |
make info | Build-Konfiguration anzeigen |
Use Cases
- Web-Frameworks — Laravel, Symfony, Slim, Custom
- REST-APIs & GraphQL — JSON-Endpoints mit FastCGI-Optimierung
- Single-Page-Apps — Static-Asset-Serving mit 1-Jahr-Cache
- E-Commerce & SaaS — Produktions-Stack mit Pool-Tuning
- WordPress & CMS — Standard-PHP-Anwendungen