Summary
Updating packages on the host does not affect PHP inside a container. Pull a fresh base image, rebuild your own image, and restart the containers. Check the version inside the container, not on the host.
Step 1. Find out what is inside
docker ps --format '{{.Names}}\t{{.Image}}'
docker exec -it container_name php -v
docker exec -it container_name sh -c 'dpkg -l | grep php || rpm -q php-cli'The official PHP images are built from source, so the version number is reliable: 8.3.36 and newer is fixed, 8.3.35 and older is not.
Step 2. Update the base image
If the Dockerfile pins an exact tag, raise it to a fixed version:
FROM php:8.3.36-fpm-bookwormIf the tag is floating (php:8.3-fpm), pulling the image again is enough:
docker pull php:8.3-fpm
docker compose build --pull --no-cache
docker compose up -dThe --pull flag is the key here: without it, the build reuses an old layer from the local cache and the vulnerability remains.
Step 3. Verify the result
docker compose exec php php -v
docker compose exec php php -r 'echo PHP_VERSION, PHP_EOL;'The version must be at least 8.3.36 for the 8.3 branch, 8.4.27 for 8.4, 8.5.12 for 8.5, and 8.2.35 for 8.2.
Step 4. Make sure no old containers are still running
A common mistake: the image is updated, but a container started a week ago is still running next to it.
docker ps --format '{{.Names}}\t{{.Image}}\t{{.CreatedAt}}'If a container was created before you rebuilt the image, recreate it.
Preventing a repeat
- Pin exact version tags, so you can see what is deployed.
- Rebuild images on a schedule, not only when the code changes: a base image goes stale on its own.
- Add an image vulnerability scan to your pipeline:
docker scout cves image_nameortrivy image image_name.
Frequently asked questions
Do I need to update PHP on the host if everything runs in Docker containers?
If PHP is not used on the host, no. But check: tools such as composer or cron scripts may have pulled in a system PHP.
Is the Alpine PHP image also vulnerable to PHP2Shell?
Yes. The vulnerable code is PHP itself, not the distribution. Update it the same way.
How do I quickly check PHP versions in all running Docker containers?
for c in $(docker ps -q); do printf '%s ' "$(docker inspect -f '{{.Name}}' $c)"; docker exec $c php -v 2>/dev/null | head -1 || echo 'no php'; done