PHP-FPM / CLI images with common extensions and PrestaShop chmod(0) shim. PHP 7.0–8.5.
10K+
PHP-FPM and PHP-CLI images with the extensions most PHP projects actually reach
for already compiled in (gd, intl, imagick, redis, memcached, pdo_mysql,
pdo_pgsql, opcache, soap, zip, zstd, …), a healthcheck that verifies the pool
rather than the socket, and a small LD_PRELOAD shim for the PrestaShop
chmod(0) cache bug.
Defaults are sized for PrestaShop-class applications — 1 GB memory_limit, long
max_execution_time, large uploads. Drop your own .ini at
/usr/local/etc/php/conf.d/99-php.ini to override anything.
{version}-{flavor}. There is no latest: a PHP image whose tag doesn't name
the version is a trap.
| Flavor | What it's for | PHP versions |
|---|---|---|
fpm | PHP-FPM behind a reverse proxy (nginx / Angie / Caddy) | 7.0 – 8.5 |
cli | One-shot PHP CLI for cron jobs, queue workers, scripts | 8.3, 8.4, 8.5 |
cli-builder | Build stage: CLI + git, composer, node, npm, brotli, sqlite3 | 7.4, 8.3, 8.4, 8.5 |
Multi-arch: linux/amd64, linux/arm64. Every image carries an SBOM, max-mode
build provenance and a keyless Cosign signature:
cosign verify dementev/php-fpm-with-ext:8.5-fpm \
--certificate-identity-regexp '^https://github\.com/vdementev/docker-php-fpm-with-ext/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
PHP 8.1 and older are end of life upstream and are published here unpatched, on purpose, for legacy applications being migrated rather than rewritten.
7.0–8.0are frozen: PECL no longer serves extension sources for them, so those tags keep working but cannot be rebuilt from scratch. The full matrix and what "supported" means for each row is in SUPPORT.md.
fpm-health wired up as a Docker HEALTHCHECK: it wraps
php-fpm-healthcheck (renatomefi), requires a real status page back
rather than just an open socket, and walks every pool listed in
FPM_HEALTH_PORTS (comma-separated, default 9000) so a container
running more than one pool reports unhealthy when any of them dies.
pm.status_path = /status and ping.path = /ping are set in the
bundled www.conf — a replacement www.conf has to keep
pm.status_path, or the healthcheck will (correctly) fail.STOPSIGNAL SIGQUIT so docker stop triggers FPM's graceful
worker drain instead of an immediate SIGTERM kill.jq, less, mariadb-client, nano, procps, rsync,
unzip, zip, zstd, fcgi/libfcgi-bin (for the healthcheck
binary). unzip is a separate package from zip — deploy scripts
that shell out to it need both.www-data by default. WORKDIR /app.cli: same extension set as FPM, minus the FPM healthcheck and shim.
Adds git on top of the FPM tool list.cli-builder: adds git, composer, node, npm,
semantic-release, brotli, sqlite3, pdo_sqlite for CI usage.CMD ["sh"] on cli-builder. Runs as www-data.chmod(0) shimPrestaShop's cache regeneration (module reset/install, cache clear,
debug-mode toggle) invalidates files like appParameters.php,
class_index.php, and namespaced_class_stub.php by calling
chmod($file, 0000) and then rewriting them. If the rewrite fails or
races, the files stay at mode 0000 and every subsequent request
returns a 500 until permissions are manually fixed. Reported upstream
since PS 1.7.4, still present in 8.2.x
(PS issues #10998, #13050, #30786, #37666).
The FPM images ship /usr/local/lib/php-chmod-sanitize.so, an
LD_PRELOAD shim that intercepts chmod, fchmod, and fchmodat.
When called with mode 0, the shim promotes the call to 0644 for
regular files and 0755 for directories. Non-zero modes pass through.
Not active by default — enable it per project:
services:
php:
image: dementev/php-fpm-with-ext:8.3-fpm
environment:
LD_PRELOAD: /usr/local/lib/php-chmod-sanitize.so
LD_PRELOAD applies to every process in the container (FPM workers,
CLI, composer), so any genuine chmod($x, 0) anywhere will also be
rewritten — for PrestaShop that's the desired behavior. CLI / CLI-
builder variants do not ship the shim. The shim masks the bug
rather than fixing it — track upstream PS fixes.
FROM dementev/php-fpm-with-ext:8.3-fpm
COPY 99-app.ini /usr/local/etc/php/conf.d/99-app.ini
COPY www.conf /usr/local/etc/php-fpm.d/www.conf
01-php.ini is the image-default; anything in 99-*.ini overrides it.
Defaults worth knowing before you override them:
disable_functions blocks the process-spawning family as a whole
(exec, shell_exec, passthru, system, popen, proc_*,
pcntl_exec) plus dl, show_source/highlight_file. It does not
block getmypid/getmyuid/diskfreespace — those break real
libraries and blocked nothing (posix_getpid, disk_free_space).
The cli-builder images set no disable_functions at all, since
composer and npm need to spawn processes.max_accelerated_files = 32531, enable_file_override = 0 and JIT
off (opcache.jit = disable, jit_buffer_size = 0).Published digests are signed and carry an SBOM and build provenance. This
repository has not yet moved to the shared PR-gated pipeline with a Trivy scan
gate that the other dementev/* images use — a push to main publishes
directly. That gap is stated rather than glossed over; see
SECURITY.md
for the reporting channel and response targets.
One family, built by the same pipeline, meant to run together — a proxy in front, an app runtime, a database, and a way into it.
| Image | What it does |
|---|---|
dementev/angie — source | Public-facing reverse proxy and TLS terminator — Angie, the nginx fork, with brotli, zstd and cache-purge |
dementev/nginx — source | Static sites and SPAs behind that proxy — brotli/zstd siblings, Prometheus stub_status |
dementev/php-fpm-with-ext — this image | PHP-FPM and CLI, PHP 7.0 → 8.5, with the extensions most projects reach for |
dementev/mysql-percona — source | Percona Server for MySQL 8.4 LTS, XtraBackup built in, no root inside |
dementev/adminer — source | Adminer 6 with every driver it supports, for reaching any of the above |
Built and maintained by Vasilii Dementev at Lotus Web Agency. These images are not a side project — they are the base layer under the client and product systems we run, which is why they are gated, tested and signed rather than pushed by hand.
Issues and pull requests: github.com/vdementev/docker-php-fpm-with-ext. Need this kind of infrastructure built or maintained for your own stack? lotuswebagency.com.
Packaging in this repository is MIT licensed — see LICENSE. The software inside the image keeps its own upstream licenses.
Content type
Image
Digest
sha256:1d6f68f27…
Size
312.2 MB
Last updated
4 days ago
docker pull dementev/php-fpm-with-ext:8.5-cli