# Official PHP Docker Images: Tags, Digests and Rebuilds

> PHP Docker image tags explained: version tags, variants such as fpm and apache, digests, and how to check before use whether an image closes PHP2Shell.

Source: https://phpsos.de/en/blog/offizielle-php-docker-images/  
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:** The official PHP image on Docker Hub comes in many tags that combine version, variant (such as cli, fpm, apache) and base system. A tag is a pointer that moves to new states after rebuilds; only the digest identifies exactly one state. Against PHP2Shell you need an image with PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, verified with `php -v`, and a rebuild of your own images on top of it.

## Why the tag alone reveals little

Many teams write a line like `FROM php:8.3-fpm` in their Dockerfile and then forget it. That works as long as nobody asks which PHP version is actually running. Since PHP2Shell, everybody asks.

The answer is not in the Dockerfile. A tag such as `8.3-fpm` points, at the time of pulling, to the latest state of that branch. If the image was pulled before 21 October and not renewed since, it contains a vulnerable version, even though the tag now points to a fixed state. According to the guidelines of the Docker Official Images, the images are actively rebuilt, including for security fixes. Your local copy is not affected by that.

The complete procedure from rebuild to newly created container is described in [Patching PHP in Docker containers](https://phpsos.de/en/php2shell/docker-container-patchen/). This article is about the prior question: which image is the right one, and how do you prove its status?

## PHP Docker image tags: how they are built

Tags consist of up to three parts. Docker Hub shows examples such as `php:8.2-cli`, `php:8.2-fpm-alpine` or `php:8.4.27-zts-alpine3.24`.

| Component | Example | Meaning |
|---|---|---|
| Version | `8.4.27` or `8.4` | the full version stays at this state, the branch specification moves with new patches |
| Variant | `cli`, `fpm`, `apache`, `zts` | operating mode of PHP in the container |
| Base system | `alpine3.24`, `bookworm`, `trixie` | underlying Alpine or Debian version |

The variants are not equivalent for PHP2Shell. `fpm` runs PHP-FPM, `apache` runs PHP as an Apache module, that is, mod_php. The PHP team rates this operating mode highest because an exploit was demonstrated there before any application code even runs. More at [Why mod_php is especially at risk](https://phpsos.de/en/php2shell/mod-php-risiko/). The `cli` variant is intended for command-line tasks.

The base system also has consequences. Alpine images are small but use a different C library than Debian images; some extensions or precompiled libraries behave differently there. So do not change the base system on the side with the security update, but stay with what your application knows for now.

Important for understanding: in the official image, PHP does not come from the packages of the base distribution. Docker Hub describes that the PHP sources are in the image and extensions are built in via helper scripts such as `docker-php-ext-install`. A package update of the base system in your own Dockerfile therefore changes nothing about the PHP version. All that matters is which state of the official image you build on.

## Tag or digest: what changes when

A digest is a checksum over the contents of an image, written as `sha256:` followed by a long string. It changes with every rebuild. That makes it suitable as proof: whoever knows the digest knows exactly which state is running.

A division of labor has proven itself in practice:

- **In the Dockerfile**, use the branch tag, such as `php:8.4-fpm`, so that a rebuild automatically gets the latest patch of that branch.
- **In the rollout**, use the digest of your finished, built image so that it is unambiguous what is delivered.
- **In the documentation**, record both: tag, digest and the version verified with `php -v`.

Whoever pins a full version tag such as `8.3.35-fpm` instead never automatically gets a patch. That may be intended, but it requires a process that raises the tag with every security announcement.

## PHP2Shell: checking an image before use

The following commands pull an image and read information. They do not change running containers.

```bash
# Pull the current state of the branch tag
docker pull php:8.4-fpm

# Which PHP version is in the image?
docker run --rm php:8.4-fpm php -v

# Show the digest of the pulled image
docker image inspect php:8.4-fpm --format '{{index .RepoDigests 0}}'

# Query digest and platforms directly in the registry
docker buildx imagetools inspect php:8.4-fpm
```

For multi-platform images, the `imagetools` query shows a top-level digest and below it one digest per platform, such as linux/amd64 or linux/arm64. Document the digest that your servers actually pull, and note that developer machines with a different architecture get a different platform digest.

If `php -v` does not show at least the fixed version of the branch, the image is outdated or comes from a cache. Then check whether your environment uses a registry mirror that serves old states.

For PHP 8.1 and older, the PHP project provides no official releases. An official image of these branches can therefore not contain a regular fixed version. According to the Docker guidelines, tags that are no longer maintained remain retrievable but are no longer updated.

> **Tip:**
> According to Docker Hub, the image ships with `php.ini-development` and `php.ini-production` and strongly recommends the production version for production operation. Put your own settings, including the interim values from php.net, as a file in `$PHP_INI_DIR/conf.d/`.

## Typical mistakes when choosing an image

- **Variant out of habit:** The apache variant is chosen because it starts easily, although fpm with a separate web server would be possible.
- **No rebuild of your own images:** The base image is current, the application image built from it is not.
- **Multi-stage builds overlooked:** In a Dockerfile with several `FROM` lines, only one is adjusted.
- **Side images forgotten:** Workers, cron containers and admin tools use their own tags.
- **Relying only on `latest`:** The tag says nothing about branch and variant and can jump unexpectedly with a new main branch.

How to automate rebuilds so that an outdated image does not run for long in the first place is described in [CI/CD: automatically rebuilding PHP images](https://phpsos.de/en/blog/php-images-in-ci-neu-bauen/). Basics on PHP in containers are explained in [PHP in containers](https://phpsos.de/en/php/php-in-containern/).

## How does PHP SOS help?

- **Check the inventory:** We read out which tags, digests and PHP versions are in your images and running containers.
- **Assess the variant:** We check whether mod_php is necessary or whether fpm with a separate web server reduces the risk.
- **Rebuild and prove:** With the [PHP patch service](https://phpsos.de/en/leistungen/php-patch-service/), we rebuild images on a fixed base and document tag, digest and version.
- **Anchor the process:** We set up Dockerfiles and rollouts so that the next patch arrives in a plannable way.


## Frequently asked questions

**What is the difference between a tag and a digest?**  
A tag such as php:8.4-fpm is a name that can point to a new state after every rebuild. A digest is a checksum that identifies exactly one immutable state. For proof and reproducible rollouts, the digest is the more reliable specification.

**Which tag contains the PHP2Shell fix?**  
The fixed versions are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. A tag with the full version number shows the state directly. With shorter tags such as 8.4-fpm, check with php -v after pulling which version is actually contained.

**Is there a patched official image for PHP 8.1?**  
The PHP project no longer provides official releases for 8.1 and older. An official image of these branches can therefore not contain a regular fixed version. Plan the move to a supported branch.

**Is the apache variant riskier than fpm?**  
The apache variant runs PHP as an Apache module, that is, mod_php. The PHP team rates this operating mode highest for PHP2Shell. Both variants need the update; with mod_php, speed is especially important.

## Sources

- [Docker Hub: Official PHP image](https://hub.docker.com/_/php)
- [Docker documentation: docker buildx imagetools inspect](https://docs.docker.com/reference/cli/docker/buildx/imagetools/inspect/)
- [Docker Official Images: Guidelines and maintenance](https://github.com/docker-library/official-images)
- [php.net: Security announcements](https://www.php.net/)
