# Patching PHP in Docker Containers

> Update your PHP Docker image against PHP2Shell: check the version in the container, rebuild the image, recreate containers and set interim values.

Source: https://phpsos.de/en/php2shell/docker-container-patchen/  
As of: 25/10/2026  
Provider: PHP SOS, PHP emergency help and server security. Immediate help via WhatsApp: https://wa.me/491736494914?text=Hello%20PHP%20SOS%2C%20we%20need%20help%20with%20our%20PHP%20server.%20Company%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**In short:** Updating the PHP Docker image is mandatory against PHP2Shell, and it does not happen by itself. You have to rebuild or pull the image with a fixed PHP version, recreate every container from it and verify that 8.5.12, 8.4.27, 8.3.36 or 8.2.35 is running in the live container. A simple container restart is not enough.

## Why containers are not automatically secure

A Docker image is a frozen snapshot. The PHP inside stays at the state it had when the image was built, even if updates were long ago installed on the host. A package update on the host system changes nothing about the PHP in the container.

Typical pitfalls add to this: images that were built months ago and not touched since, base images with a fixed tag such as `php:8.3.35-fpm`, local caches that reuse the old base image during the build, and containers that were restarted but never recreated. All operating modes that are common in containers are affected: PHP-FPM, Apache with mod_php and FrankenPHP.

There is also a question of responsibility. In many companies, an agency or developer built the image once, but it is operated by the internal IT team or a hosting provider. Then nobody feels responsible for the PHP version in the image. So first clarify who builds the image, where the Dockerfile is kept and who may roll out new images.

## Checking the PHP version in the container

Check the running container, not just the Dockerfile. The commands are read-only.

```bash
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.CreatedAt}}"
docker exec <container> php -v
docker exec <container> php -i | grep -E "^PHP Version|Server API"
docker image inspect <image> --format "{{.Created}}"
```

If the image uses distribution packages instead of official PHP builds, check the package version in the container. Package names differ by base distribution:

```bash
docker exec <container> sh -c "apt policy php8.3-fpm 2>/dev/null || apk info -v 2>/dev/null | grep php"
```

With distribution packages, a backport may be applied although the version number stays old. In that case the package changelog counts. The official PHP images, by contrast, usually ship PHP compiled by themselves; there the version number from `php -v` is the decisive value. How to recognise backports is described in [Checking the PHP version and patch level correctly](https://phpsos.de/en/php2shell/php-version-pruefen/).

## Updating the PHP Docker image: rebuild and roll out

**Your own image based on a PHP image:** pull the base image again and build without cache.

```bash
docker build --pull --no-cache -t meine-app:2026-10-25 .
docker run --rm meine-app:2026-10-25 php -v      # check the version before rolling out
```

**With Docker Compose:** pull or build images and recreate containers.

```bash
docker compose pull
docker compose build --pull --no-cache
docker compose up -d --force-recreate
```

Afterwards check again with `docker exec <container> php -v` that the new version is running. If the container has a fixed version tag in the Dockerfile, for example `FROM php:8.3.35-fpm`, you have to raise the tag. A tag on the branch such as `php:8.3-fpm` receives new patch versions, but only if you pull again.

Keep the previous image ready until the new version has been tested. In case of an error you can then switch back without leaving the application offline for long. The old image, however, contains the vulnerable PHP again; a rollback is therefore only defensible briefly and together with the interim measures.

If you use Kubernetes, you roll out the new image through the deployment. Details are at [Patching PHP in Kubernetes](https://phpsos.de/en/server/kubernetes/). The same procedure applies to FrankenPHP images; notes on the operating mode can be found at [Securing FrankenPHP](https://phpsos.de/en/server/frankenphp/).

> **Important:**
> Do not forget side containers: cron and queue workers, admin tools or staging environments often use the same PHP image but run in their own containers. Every one of them must be recreated.

## Interim measures in the container

If the update is not yet possible, the interim measures from php.net also apply in the container. They are not full protection. The memory limit belongs on the container, because php.net recommends it via container or cgroup, not via `RLIMIT_AS` or `RLIMIT_DATA`:

```ini
; e.g. as a file in the image: /usr/local/etc/php/conf.d/zz-uebergang.ini
memory_limit = -1
post_max_size = 8M
upload_max_filesize = 6M
session.upload_progress.enabled = 0
```

```bash
docker run --memory=1g ...         # or in Compose: deploy.resources.limits.memory
```

You adjust the value to your application. Make sure the application cannot override `memory_limit` itself; with PHP-FPM, you set the values for this in the pool with `php_admin_value`. New configuration only takes effect once the container has been recreated or restarted; the background on restarting is explained at [Restarting PHP-FPM and all workers](https://phpsos.de/en/php2shell/php-fpm-neustart/).

## So that it goes faster next time

- Rebuild images regularly and automatically, not only on code changes.
- Use base images with a branch tag and version the built state with a date or digest.
- Have images scanned for known vulnerabilities before rollout and run containers without root rights.
- Keep an inventory of which containers use which image.

## How does PHP SOS help?

- **Take stock:** We check all running containers, their images and PHP versions, including side containers and staging.
- **Rebuild and roll out:** Through the [PHP patch service](https://phpsos.de/en/leistungen/php-patch-service/), we build the images with the fixed version and recreate the containers in a controlled way.
- **Secure the transition** where the update depends on the application: php.net values, memory limit on the container.
- **Monitor permanently:** With [security monitoring](https://phpsos.de/en/leistungen/security-monitoring/), we keep an eye on image versions and unusual container behavior.


## Frequently asked questions

**Is docker restart enough after the update?**  
No. docker restart restarts the container with the same, old image. You have to build or pull the new image and recreate the container from it, for example with docker compose up -d --force-recreate.

**Does the official PHP image already contain the fixed version?**  
It is best to check this directly: pull the image again and run php -v inside it. Expected are 8.5.12, 8.4.27, 8.3.36 or 8.2.35. If the image shows an older number, it has not been updated yet or comes from a cache.

**Is PHP in a container less at risk than on the host?**  
The vulnerability itself works the same in a container. A well-built container can limit the consequences of a break-in, for example through a non-root user and a read-only file system. It does not replace the patch.

## Sources

- [php.net: Security announcements](https://www.php.net/)
- [PHP 8 ChangeLog](https://www.php.net/ChangeLog-8.php)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
