PHP 8.4 ZTS (thread-safe) Apache Docker image with event MPM, mod_apex and OPcache; no PHP-FPM
1.1K
PHP 8.4 ZTS (thread-safe) Apache Docker image with event MPM, mod_apex and OPcache; no PHP-FPM.
One container. One request path. PHP ready inside Apache.
practicalwebuser/mod_apex-apache:php8.4 puts Apache, PHP 8.4.27 ZTS, and PHP
Apex in one ready-to-run image. PHP executes directly in Apache's worker
threads, so you avoid a separate PHP-FPM container, FastCGI socket, and second
request queue.
Run modern PHP applications with one web service and no separate PHP-FPM process pool. Keep Apache's event MPM without going back to legacy prefork mod_php.
The image automatically sizes its worker pool from the container's effective CPU and memory limits. A 2-CPU, 2-GiB container selects four workers, disables keep-alive, and keeps its first Apache child persistent.
The image is ready with the web server, PHP runtime, module wiring, and common extensions already together:
mod_apex) enabled for .php filesmysqli and PDO MySQL/healthzThe runtime uses Debian 13 (Trixie) Slim. Compilers and build tools are not kept in the published runtime image.
mkdir -p "$(pwd)/app"
test -e "$(pwd)/app/healthz" || printf 'ok\n' > "$(pwd)/app/healthz"
docker pull practicalwebuser/mod_apex-apache:php8.4
docker run -d --name my-php-app \
--cpus=2 --memory=2g \
-p 8080:80 \
-v "$(pwd)/app:/var/www/html:ro" \
practicalwebuser/mod_apex-apache:php8.4
Open http://your-server:8080. Your application belongs in ./app.
The example mounts application code read-only. If your application writes uploads, cache files, or generated content, mount only those directories as separate writable volumes.
A bind mount on /var/www/html hides the image's bundled static /healthz, so
the example creates a replacement in the mounted application. Keep that file
in the deployed document root, or bake the application into a derived image;
otherwise Docker reports the container as unhealthy when its health check gets
a 404 response.
docker logs, and includes /healthz.Set CPU and memory limits with your container platform. PHP Apex uses two workers per effective CPU, capped by a conservative memory budget. Keep-alive remains disabled unless explicitly enabled. For a 2-CPU, 2-GiB container, start with:
docker run -d --name my-php-app \
--cpus=2 --memory=2g \
-p 8080:80 \
practicalwebuser/mod_apex-apache:php8.4
Important: do not manually override Apache's ServerLimit, ThreadLimit,
ThreadsPerChild, or MaxRequestWorkers directives. The PHP Apex entrypoint
automatically generates these settings as one valid layout from the available
CPU and memory. Changing only one directive can make Apache silently run a
different number of workers, increasing memory use or reducing performance.
Use the documented APEX_* environment variables only when a measured
deployment requires an override.
For a measured high-traffic deployment, enable keep-alive and set a worker limit from 1 to 512:
docker run -d --name my-php-app \
--cpus=2 --memory=2g \
-e APEX_KEEP_ALIVE=1 \
-e APEX_MAX_REQUEST_WORKERS=8 \
-p 8080:80 \
-v "$(pwd)/app:/var/www/html:ro" \
practicalwebuser/mod_apex-apache:php8.4
Let automatic sizing establish the baseline. Enable APEX_KEEP_ALIVE=1 and
override the worker limit only for a measured high-traffic deployment.
APEX_KEEP_ALIVE accepts only 0 or 1. The entrypoint always generates a
valid event-MPM layout; if a worker override cannot be represented exactly
within its eight-child, 64-thread envelope, it logs the small safe downward
adjustment.
The default APEX_MAX_CONNECTIONS_PER_CHILD=0 keeps the single baseline child
persistent. Multi-child deployments can test 1000 or 10000 to enable
count-based recycling; measure memory, restarts, and latency before changing it.
OPcache is optimized for immutable containers by default. If PHP code can change while the container is running, enable timestamp validation so those changes are loaded:
docker run -d --name my-php-app \
-e APEX_OPCACHE_VALIDATE=1 \
-p 8080:80 \
-v "$(pwd)/app:/var/www/html" \
practicalwebuser/mod_apex-apache:php8.4
Keep the default APEX_OPCACHE_VALIDATE=0 for code baked into the image or
mounted read-only. Set it to 1 for writable PHP code, including
volume-mounted WordPress plugins and themes. Only 0 and 1 are accepted.
PHP version headers are disabled, and session cookies default to HttpOnly
with SameSite=Lax. Applications can override their own cookie policy.
If customers can upload PHP code, opt into tighter process and URL access:
docker run -d --name my-php-app \
-e APEX_DISABLE_FUNCTIONS=exec,passthru,shell_exec,system,proc_open,popen \
-e APEX_ALLOW_URL_FOPEN=0 \
-p 8080:80 \
practicalwebuser/mod_apex-apache:php8.4
The disabled-function list is empty by default because some applications use
proc_open. APEX_ALLOW_URL_FOPEN defaults to 1. It and the other Boolean
image settings accept only 0 or 1.
The image includes mod_remoteip but trusts no network automatically. For a
Traefik network such as 10.89.0.0/16, set:
-e APEX_TRUSTED_PROXY="10.89.0.0/16"
Space-separate multiple trusted CIDRs. In a Cloudflare → Traefik deployment,
Traefik must validate and sanitize Cloudflare's forwarded headers, or PHP Apex
must also receive the current Cloudflare proxy ranges. Do not use
0.0.0.0/0. Confirm $_SERVER['REMOTE_ADDR'] before using it for security
decisions.
The default virtual host uses AllowOverride All, so applications can use
standard Apache .htaccess directives, including rewrites. mod_apex does
not register php_value or php_admin_value; use a mounted PHP INI file for
PHP settings.
Check availability without invoking PHP:
curl -fsS http://127.0.0.1:8080/healthz
docker logs my-php-app
/healthz is a small static check for container and load-balancer monitoring.
The image does not publish /test.php by default. You can temporarily set
APEX_ENABLE_TEST_PAGE=1 for a private PHP smoke test. That option overwrites
/var/www/html/test.php, requires a writable document root, and is not
compatible with the read-only bind mount above. On a writable host mount, the
file persists after the container stops; delete it and remove the setting
before public exposure.
The image serves HTTP on port 80. Put TLS certificates and public internet traffic at your reverse proxy or load balancer.
| Tag | Use |
|---|---|
php8.4 | Current PHP 8.4.27 ZTS, Apache, and PHP Apex v0.1.10 |
The tag is updated in place. Its current digest is
sha256:e9ef0395e468139755143f0a0a1052b915b05e33aea3164520e5697423aeed69.
For repeatable production deployments, pull and test the tag, then pin its
digest in your deployment configuration.
See the Docker guide for writable application directories, custom Apache/PHP settings, proxy setup, and upgrade guidance.
PHP Apex is released under the Apache License 2.0. PHP, Apache HTTP Server, and bundled extensions retain their respective licenses.
Content type
Image
Digest
sha256:c7317680e…
Size
129.9 MB
Last updated
3 days ago
docker pull practicalwebuser/mod_apex-apache:php8.4