Skip to content
Merged
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@

### Minor changes

* **2026-11-03**
* The `php` command is about 20 ms faster on each call: it detects the changes of the `PHP_*` environment variables without starting PHP a first time. The configuration is now also regenerated when a `PHP_*` variable is removed
* The README recommends the fpm variant with its built-in Apache to serve a web application, and links to the v6 roadmap. The php2shell fix is now mentioned in the supported versions
* New documentation of the fpm variant: application outside `/var/www/html` and additional PHP-FPM pools (#190)

* **2026-10-23**
* Security: php2shell is fixed in the arm64 images too, now that the fixed PHP packages are published for arm64. The php2shell test fails again for a vulnerable image on every architecture
* The tags of the PHP patch versions (e.g. `8.5.12-v5-cli`) are published again: they were no longer published since 2025-12-10. The `X.Y-v5-*` tags are not affected
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile.slim.apache
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ COPY utils/select_composer_version.sh /usr/local/bin/select_composer_version.sh
COPY utils/utils.php /usr/local/bin/utils.php
RUN mv /usr/bin/php /usr/bin/real_php
COPY utils/php_proxy.sh /usr/bin/php
COPY utils/check_php_env_var_changes.php /usr/local/bin/check_php_env_var_changes.php
COPY utils/php_env_var_cache.php /opt/php_env_var_cache.php
COPY utils/php_env_fingerprint.sh /usr/local/bin/php_env_fingerprint.sh
RUN touch /opt/php_env_fingerprint
COPY utils/generate_conf.php /usr/local/bin/generate_conf.php
COPY utils/setup_extensions.php /usr/local/bin/setup_extensions.php

Expand Down
4 changes: 2 additions & 2 deletions Dockerfile.slim.cli
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ COPY utils/select_composer_version.sh /usr/local/bin/select_composer_version.sh
COPY utils/utils.php /usr/local/bin/utils.php
RUN mv /usr/bin/php /usr/bin/real_php
COPY utils/php_proxy.sh /usr/bin/php
COPY utils/check_php_env_var_changes.php /usr/local/bin/check_php_env_var_changes.php
COPY utils/php_env_var_cache.php /opt/php_env_var_cache.php
COPY utils/php_env_fingerprint.sh /usr/local/bin/php_env_fingerprint.sh
RUN touch /opt/php_env_fingerprint
COPY utils/generate_conf.php /usr/local/bin/generate_conf.php
COPY utils/setup_extensions.php /usr/local/bin/setup_extensions.php

Expand Down
4 changes: 2 additions & 2 deletions Dockerfile.slim.fpm
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ COPY utils/select_composer_version.sh /usr/local/bin/select_composer_version.sh
COPY utils/utils.php /usr/local/bin/utils.php
RUN mv /usr/bin/php /usr/bin/real_php
COPY utils/php_proxy.sh /usr/bin/php
COPY utils/check_php_env_var_changes.php /usr/local/bin/check_php_env_var_changes.php
COPY utils/php_env_var_cache.php /opt/php_env_var_cache.php
COPY utils/php_env_fingerprint.sh /usr/local/bin/php_env_fingerprint.sh
RUN touch /opt/php_env_fingerprint
COPY utils/generate_conf.php /usr/local/bin/generate_conf.php
COPY utils/setup_extensions.php /usr/local/bin/setup_extensions.php

Expand Down
30 changes: 17 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@

# General purpose PHP images for Docker

> **Security: php2shell (CVE-2026-109618 and CVE-2026-109619, CVSS 9.2) is fixed in all the v5 images**
>
> Pull the images again, recreate your containers and rebuild the images built from ours. **Update:** the arm64 images,
> first published without the fix, are now fixed too: pull them again. The v4 images are **not** fixed: migrate to
> v5. See [what to do](docs/security-php2shell.md).
> **The fpm variant has a built-in Apache** (`PHP_FPM_WEB_SERVER=apache`): the same features as the `apache` variant,
> with 2 to 3 times more traffic served and 4 times less memory ([benchmark](benchmarks/fpm-apache/README.md)). It is
> the recommended variant to serve a web application: see [Serving with the fpm variant](docs/fpm.md).

This repository contains a set of developer-friendly, general purpose PHP images for Docker.

- You can enable or disable the extensions using environment variables.
- You can also modify the `php.ini` settings using environment variables.
- 2 types available: `slim` (no extensions preloaded) or `fat` (most common PHP extensions are built-in)
- 3 variants available: `CLI`, `apache` and `fpm` (with an optional built-in Apache)
- 3 variants available: `CLI`, `apache` and `fpm` (with an optional built-in Apache, recommended for web applications)
- Fat images are bundled with [Supercronic](https://github.com/aptible/supercronic) which is a Cron compatible task runner. Cron jobs can be configured using environment variables
- All images come with [Composer](https://getcomposer.org/) installed
- All variants can be installed with or without NodeJS (if you need to build your static assets).
Expand Down Expand Up @@ -143,7 +141,8 @@ Bugs are fixed on maintained versions only.
| 20 | **Not maintained** (end of life: 2026-04-30) |

Images of non-maintained versions are still available but no longer receive fixes: use them at your own risk and plan your upgrade.
Critical vulnerabilities may get an exceptional fix (e.g. [php2shell](docs/security-php2shell.md)).
Critical vulnerabilities may get an exceptional fix: [php2shell](docs/security-php2shell.md) (CVE-2026-109618 and
CVE-2026-109619) is fixed in all the v5 images, not in the v4 ones.

## Usage

Expand All @@ -155,22 +154,22 @@ Example with CLI:
$ docker run -it --rm --name my-running-script -v "$PWD":/usr/src/app thecodingmachine/php:8.4-v5-cli php your-script.php
```

Example with Apache:
Example with PHP-FPM and its built-in Apache (in the same container), recommended to serve a web application:

```bash
$ docker run -p 80:80 --rm --name my-apache-php-app -v "$PWD":/var/www/html thecodingmachine/php:8.4-v5-apache
$ docker run -p 80:80 --rm --name my-apache-fpm-app -e PHP_FPM_WEB_SERVER=apache -v "$PWD":/var/www/html thecodingmachine/php:8.4-v5-fpm
```

Example with PHP-FPM:
Example with PHP-FPM alone, behind your own web server:

```bash
$ docker run -p 9000:9000 --rm --name my-php-fpm -v "$PWD":/var/www/html thecodingmachine/php:8.4-v5-fpm
```

Example with PHP-FPM and its built-in Apache (in the same container):
Example with Apache and `mod_php`:

```bash
$ docker run -p 80:80 --rm --name my-apache-fpm-app -e PHP_FPM_WEB_SERVER=apache -v "$PWD":/var/www/html thecodingmachine/php:8.4-v5-fpm
$ docker run -p 80:80 --rm --name my-apache-php-app -v "$PWD":/var/www/html thecodingmachine/php:8.4-v5-apache
```

Example with Apache + Node 24.x in a Dockerfile:
Expand Down Expand Up @@ -198,7 +197,6 @@ Most features are configured with environment variables:
| [Processes](docs/processes.md) | Startup commands, cron jobs and daemons run along with the main command | `STARTUP_COMMAND_*`, `CRON_*`, `DAEMON_*` |
| [Debugging and profiling](docs/debugging.md) | Xdebug and Blackfire | `PHP_EXTENSION_XDEBUG`, `XDEBUG_CLIENT_HOST`, `BLACKFIRE_AGENT` |
| [Advanced features](docs/advanced.md) | Permissions, NodeJS, Composer version, locales, SSH keys, Kubernetes | `DOCKER_USER`, `COMPOSER_VERSION`, `LOCALES` |
| [php2shell](docs/security-php2shell.md) | What to do about CVE-2026-109618 / CVE-2026-109619 | |

The slim images install some tools during the build of your image with an ARG before the `FROM`: `PHP_EXTENSIONS`,
`INSTALL_CRON`, `INSTALL_LOCALES`, `NODE_VERSION` and `COMPOSER_VERSION`.
Expand All @@ -207,6 +205,12 @@ The slim images install some tools during the build of your image with an ARG be

Check the [migration notes](MIGRATING.md).

## Roadmap

The v5 images keep receiving fixes and backward compatible features. The next major version, v6, is planned for 2027:
Ubuntu 26.04, a FrankenPHP variant and much faster builds. Follow and discuss it in the
[roadmap issue](https://github.com/thecodingmachine/docker-images-php/issues/359).

## Contributing

The Dockerfiles and this README are generated from the templates of the `utils` directory: see the
Expand Down
66 changes: 66 additions & 0 deletions docs/fpm.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,72 @@ server {
}
```

## Application directory

The application does not have to be in `/var/www/html`: PHP-FPM runs the script whose path it receives from the web
server. Mount the application in another directory and give its path to the web server: `APACHE_DOCUMENT_ROOT` with
the built-in Apache (an absolute path), the `root` of nginx... Also set the working directory: by default, the
commands run with the owner of the working directory (see [Permissions](advanced.md#permissions)).

```yml
services:
app:
image: thecodingmachine/php:8.4-v5-fpm
working_dir: /var/www
environment:
PHP_FPM_WEB_SERVER: apache
APACHE_DOCUMENT_ROOT: /var/www/public
volumes:
- .:/var/www
```

## Several pools

The `www` pool of PHP-FPM processes all the PHP requests. Another pool can process some of them with its own
settings: number of workers, `php.ini` parameters... for instance the back office of a WordPress site, with more
memory and fewer workers. Add a pool file listening on another port:

```ini
; admin-pool.conf
[admin]
listen = 9001
; Same user as the www pool (with the built-in Apache, the PHP-FPM master process runs as root)
user = ${APACHE_RUN_USER}
group = ${APACHE_RUN_GROUP}
clear_env = no
catch_workers_output = yes
decorate_workers_output = no
pm = ondemand
pm.max_children = 2
php_admin_value[memory_limit] = 512M
```

With the built-in Apache, send the requests of the back office to this pool:

```apache
# apache-admin-pool.conf
<LocationMatch "^/wp-admin/.*\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:fcgi://127.0.0.1:9001"
</If>
</LocationMatch>
```

```yml
services:
app:
image: thecodingmachine/php:8.4-v5-fpm
environment:
PHP_FPM_WEB_SERVER: apache
volumes:
- .:/var/www/html
- ./admin-pool.conf:/etc/php/8.4/fpm/pool.d/admin.conf:ro
- ./apache-admin-pool.conf:/etc/apache2/conf-enabled/admin-pool.conf:ro
```

With your own web server, send these requests to the port of the pool (`fastcgi_pass php:9001;` in a `location` of
nginx).

## Constraints of PHP-FPM

### Number of workers and memory
Expand Down
4 changes: 4 additions & 0 deletions docs/variants.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ services:

Apache runs PHP with `mod_php`. The sections below also apply to the [built-in Apache of the *fpm* variant](#built-in-apache).

To serve a new application, prefer the *fpm* variant with its built-in Apache: the same features, with 2 to 3 times
more traffic served and 4 times less memory ([benchmark](../benchmarks/fpm-apache/README.md)). See
[Serving with the fpm variant](fpm.md) and its [migration notes](fpm.md#migrating-from-the-apache-variant).

### Document root

`APACHE_DOCUMENT_ROOT` sets the document root (your "public" directory). A relative path is relative to
Expand Down
6 changes: 6 additions & 0 deletions tests-suite/php-ini.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ test_environmentErrorReporting() {
[[ "$RESULT" == "error_reporting => 3 => 3" ]]
assert_equals "error_reporting => 3 => 3" "$RESULT" "Wrong Environment error reporting"
}
test_environmentChangedAfterStart() {
RESULT="$(docker run ${RUN_OPTIONS} --rm \
"${REPO}:${TAG_PREFIX}${PHP_VERSION}-${BRANCH}-slim-${BRANCH_VARIANT}${ARCH_SUFFIX}" \
bash -c 'PHP_INI_MEMORY_LIMIT=512M php -r "echo ini_get(\"memory_limit\"), \" \";"; php -r "echo ini_get(\"memory_limit\");"')"
assert_equals "512M -1" "$RESULT" "The configuration is not regenerated when a PHP_* variable is added or removed"
}
############################################################
## PHP_INI_SESSION__SAVE_PATH
## Tests that environment variables with an equal sign are correctly handled
Expand Down
4 changes: 2 additions & 2 deletions utils/Dockerfile.slim.blueprint
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ COPY utils/select_composer_version.sh /usr/local/bin/select_composer_version.sh
COPY utils/utils.php /usr/local/bin/utils.php
RUN mv /usr/bin/php /usr/bin/real_php
COPY utils/php_proxy.sh /usr/bin/php
COPY utils/check_php_env_var_changes.php /usr/local/bin/check_php_env_var_changes.php
COPY utils/php_env_var_cache.php /opt/php_env_var_cache.php
COPY utils/php_env_fingerprint.sh /usr/local/bin/php_env_fingerprint.sh
RUN touch /opt/php_env_fingerprint
COPY utils/generate_conf.php /usr/local/bin/generate_conf.php
COPY utils/setup_extensions.php /usr/local/bin/setup_extensions.php

Expand Down
30 changes: 17 additions & 13 deletions utils/README.blueprint.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@

# General purpose PHP images for Docker

> **Security: php2shell (CVE-2026-109618 and CVE-2026-109619, CVSS 9.2) is fixed in all the v5 images**
>
> Pull the images again, recreate your containers and rebuild the images built from ours. **Update:** the arm64 images,
> first published without the fix, are now fixed too: pull them again. The v4 images are **not** fixed: migrate to
> v5. See [what to do](docs/security-php2shell.md).
> **The fpm variant has a built-in Apache** (`PHP_FPM_WEB_SERVER=apache`): the same features as the `apache` variant,
> with 2 to 3 times more traffic served and 4 times less memory ([benchmark](benchmarks/fpm-apache/README.md)). It is
> the recommended variant to serve a web application: see [Serving with the fpm variant](docs/fpm.md).

This repository contains a set of developer-friendly, general purpose PHP images for Docker.

- You can enable or disable the extensions using environment variables.
- You can also modify the `php.ini` settings using environment variables.
- 2 types available: `slim` (no extensions preloaded) or `fat` (most common PHP extensions are built-in)
- 3 variants available: `CLI`, `apache` and `fpm` (with an optional built-in Apache)
- 3 variants available: `CLI`, `apache` and `fpm` (with an optional built-in Apache, recommended for web applications)
- Fat images are bundled with [Supercronic](https://github.com/aptible/supercronic) which is a Cron compatible task runner. Cron jobs can be configured using environment variables
- All images come with [Composer](https://getcomposer.org/) installed
- All variants can be installed with or without NodeJS (if you need to build your static assets).
Expand Down Expand Up @@ -73,7 +71,8 @@ Bugs are fixed on maintained versions only.
| 20 | **Not maintained** (end of life: 2026-04-30) |

Images of non-maintained versions are still available but no longer receive fixes: use them at your own risk and plan your upgrade.
Critical vulnerabilities may get an exceptional fix (e.g. [php2shell](docs/security-php2shell.md)).
Critical vulnerabilities may get an exceptional fix: [php2shell](docs/security-php2shell.md) (CVE-2026-109618 and
CVE-2026-109619) is fixed in all the v5 images, not in the v4 ones.

## Usage

Expand All @@ -85,22 +84,22 @@ Example with CLI:
$ docker run -it --rm --name my-running-script -v "$PWD":/usr/src/app thecodingmachine/php:{{ $image.php_version }}-v5-cli php your-script.php
```

Example with Apache:
Example with PHP-FPM and its built-in Apache (in the same container), recommended to serve a web application:

```bash
$ docker run -p 80:80 --rm --name my-apache-php-app -v "$PWD":/var/www/html thecodingmachine/php:{{ $image.php_version }}-v5-apache
$ docker run -p 80:80 --rm --name my-apache-fpm-app -e PHP_FPM_WEB_SERVER=apache -v "$PWD":/var/www/html thecodingmachine/php:{{ $image.php_version }}-v5-fpm
```

Example with PHP-FPM:
Example with PHP-FPM alone, behind your own web server:

```bash
$ docker run -p 9000:9000 --rm --name my-php-fpm -v "$PWD":/var/www/html thecodingmachine/php:{{ $image.php_version }}-v5-fpm
```

Example with PHP-FPM and its built-in Apache (in the same container):
Example with Apache and `mod_php`:

```bash
$ docker run -p 80:80 --rm --name my-apache-fpm-app -e PHP_FPM_WEB_SERVER=apache -v "$PWD":/var/www/html thecodingmachine/php:{{ $image.php_version }}-v5-fpm
$ docker run -p 80:80 --rm --name my-apache-php-app -v "$PWD":/var/www/html thecodingmachine/php:{{ $image.php_version }}-v5-apache
```

Example with Apache + Node {{ $image.node_version }}.x in a Dockerfile:
Expand Down Expand Up @@ -128,7 +127,6 @@ Most features are configured with environment variables:
| [Processes](docs/processes.md) | Startup commands, cron jobs and daemons run along with the main command | `STARTUP_COMMAND_*`, `CRON_*`, `DAEMON_*` |
| [Debugging and profiling](docs/debugging.md) | Xdebug and Blackfire | `PHP_EXTENSION_XDEBUG`, `XDEBUG_CLIENT_HOST`, `BLACKFIRE_AGENT` |
| [Advanced features](docs/advanced.md) | Permissions, NodeJS, Composer version, locales, SSH keys, Kubernetes | `DOCKER_USER`, `COMPOSER_VERSION`, `LOCALES` |
| [php2shell](docs/security-php2shell.md) | What to do about CVE-2026-109618 / CVE-2026-109619 | |

The slim images install some tools during the build of your image with an ARG before the `FROM`: `PHP_EXTENSIONS`,
`INSTALL_CRON`, `INSTALL_LOCALES`, `NODE_VERSION` and `COMPOSER_VERSION`.
Expand All @@ -137,6 +135,12 @@ The slim images install some tools during the build of your image with an ARG be

Check the [migration notes](MIGRATING.md).

## Roadmap

The v5 images keep receiving fixes and backward compatible features. The next major version, v6, is planned for 2027:
Ubuntu 26.04, a FrankenPHP variant and much faster builds. Follow and discuss it in the
[roadmap issue](https://github.com/thecodingmachine/docker-images-php/issues/359).

## Contributing

The Dockerfiles and this README are generated from the templates of the `utils` directory: see the
Expand Down
34 changes: 0 additions & 34 deletions utils/check_php_env_var_changes.php

This file was deleted.

4 changes: 2 additions & 2 deletions utils/docker-entrypoint-as-root.sh
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ fi
unset DOCKER_FOR_MAC_REMOTE_HOST
unset REMOTE_HOST_FOUND

sudo chown docker:docker /opt/php_env_var_cache.php
/usr/bin/real_php -d display_errors=stderr /usr/local/bin/check_php_env_var_changes.php &> /dev/null
source /usr/local/bin/php_env_fingerprint.sh
php_env_fingerprint > /opt/php_env_fingerprint

/usr/bin/real_php -d display_errors=stderr /usr/local/bin/generate_conf.php > /etc/php/${PHP_VERSION}/mods-available/generated_conf.ini
PHP_VERSION="${PHP_VERSION}" /usr/bin/real_php -d display_errors=stderr /usr/local/bin/setup_extensions.php | sudo bash
Expand Down
7 changes: 7 additions & 0 deletions utils/php_env_fingerprint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Fingerprint of the PHP_* environment variables the PHP configuration is generated from
php_env_fingerprint() {
local name
for name in "${!PHP_@}"; do
printf '%s=%s\0' "$name" "${!name}"
done | md5sum
}
3 changes: 0 additions & 3 deletions utils/php_env_var_cache.php

This file was deleted.

Loading