# Parchear PHP en contenedores Docker

> Actualizar la imagen Docker de PHP contra PHP2Shell: comprobar la versión en el contenedor, reconstruir la imagen y recrear cada contenedor con la versión corregida.

Fuente: https://phpsos.de/es/php2shell/docker-container-patchen/  
Actualizado: 25/10/2026  
Proveedor: PHP SOS, Ayuda de emergencia para PHP y seguridad de servidores. Ayuda inmediata por WhatsApp: https://wa.me/491736494914?text=Hola%20PHP%20SOS%2C%20necesitamos%20ayuda%20con%20nuestro%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Sitio%20web%3A%20%E2%80%A6

**En resumen:** Actualizar la imagen Docker de PHP es obligatorio contra PHP2Shell, y no ocurre por sí solo. Debe reconstruir o descargar la imagen con una versión corregida de PHP, recrear cada contenedor a partir de ella y comprobar que en el contenedor en ejecución corre 8.5.12, 8.4.27, 8.3.36 u 8.2.35. Un simple reinicio del contenedor no basta.

## Por qué los contenedores no son seguros automáticamente

Una imagen de Docker es una instantánea congelada. El PHP que contiene se queda en el estado que tenía al construirla, aunque en el host se hayan instalado actualizaciones hace tiempo. Una actualización de paquetes en el sistema anfitrión no cambia nada del PHP del contenedor.

A ello se suman obstáculos típicos: imágenes construidas hace meses y no tocadas desde entonces, imágenes base con una etiqueta fija como `php:8.3.35-fpm`, cachés locales que al construir reutilizan la imagen base antigua y contenedores que se han reiniciado pero nunca se han recreado. Están afectados todos los modos de ejecución habituales en contenedores: PHP-FPM, Apache con mod_php y FrankenPHP.

Además, hay una cuestión de responsabilidad. En muchas empresas, una agencia o un desarrollador construyó la imagen una vez, pero la opera el departamento de TI interno o un proveedor de hosting. Entonces nadie se siente responsable del estado de PHP en la imagen. Aclare por eso primero quién construye la imagen, dónde está el Dockerfile y quién puede desplegar imágenes nuevas.

## Comprobar la versión de PHP en el contenedor

Compruebe el contenedor en ejecución, no solo el Dockerfile. Los comandos son de solo lectura.

```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}}"
```

Si la imagen usa paquetes de la distribución en lugar de las compilaciones oficiales de PHP, compruebe el estado del paquete en el contenedor. Los nombres de los paquetes varían según la distribución base:

```bash
docker exec <container> sh -c "apt policy php8.3-fpm 2>/dev/null || apk info -v 2>/dev/null | grep php"
```

En los paquetes de distribuciones puede haberse instalado un backport aunque el número de versión siga siendo antiguo. Entonces cuenta el changelog del paquete. Las imágenes oficiales de PHP, en cambio, suelen traer PHP compilado por ellas mismas; allí el número de versión de `php -v` es el valor determinante. Cómo reconocer los backports se describe en [Comprobar correctamente la versión de PHP y el estado del parche](https://phpsos.de/es/php2shell/php-version-pruefen/).

## Actualizar la imagen Docker de PHP: reconstruir y desplegar

**Imagen propia basada en una imagen de PHP:** descargar de nuevo la imagen base y construir sin caché.

```bash
docker build --pull --no-cache -t meine-app:2026-10-25 .
docker run --rm meine-app:2026-10-25 php -v      # comprobar la versión antes del despliegue
```

**Con Docker Compose:** descargar o construir las imágenes y recrear los contenedores.

```bash
docker compose pull
docker compose build --pull --no-cache
docker compose up -d --force-recreate
```

Después compruebe de nuevo con `docker exec <container> php -v` si se ejecuta la versión nueva. Si el contenedor tiene una etiqueta de versión fija en el Dockerfile, por ejemplo `FROM php:8.3.35-fpm`, debe subir la etiqueta. Una etiqueta de rama como `php:8.3-fpm` recibe los nuevos estados de parche, pero solo si vuelve a descargar.

Tenga preparada la imagen anterior hasta que la versión nueva esté probada. En caso de error puede volver atrás sin dejar la aplicación fuera de línea mucho tiempo. No obstante, la imagen antigua vuelve a contener el PHP vulnerable; por eso una vía de retorno solo es defendible de forma breve y con las medidas provisionales.

Quien usa Kubernetes despliega la imagen nueva mediante el Deployment. Los detalles figuran en [Parchear PHP en Kubernetes](https://phpsos.de/es/server/kubernetes/). Para las imágenes de FrankenPHP vale el mismo procedimiento; encontrará indicaciones sobre el modo de ejecución en [Proteger FrankenPHP](https://phpsos.de/es/server/frankenphp/).

> **Importante:**
> No olvide los contenedores auxiliares: los workers de cron y de colas, las herramientas de administración o los entornos de preproducción suelen usar la misma imagen de PHP, pero se ejecutan en contenedores propios. Cada uno de ellos debe recrearse.

## Medidas provisionales en el contenedor

Si la actualización aún no es posible, las medidas provisionales de php.net valen también en el contenedor. No son una protección completa. El límite de memoria debe ponerse en el contenedor, porque php.net lo recomienda mediante contenedor o cgroup, no mediante `RLIMIT_AS` ni `RLIMIT_DATA`:

```ini
; p. ej. como archivo en la imagen: /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 ...         # o en Compose: deploy.resources.limits.memory
```

Adapte el valor a su aplicación. Asegúrese de que la aplicación no pueda sobrescribir `memory_limit` por sí misma; en PHP-FPM, fije para ello los valores en el pool con `php_admin_value`. La configuración nueva solo surte efecto cuando el contenedor se ha recreado o reiniciado; los antecedentes del reinicio figuran en [Reiniciar PHP-FPM y todos los workers](https://phpsos.de/es/php2shell/php-fpm-neustart/).

## Para que la próxima vez sea más rápido

- Reconstruir las imágenes de forma periódica y automática, no solo cuando cambia el código.
- Usar imágenes base con etiqueta de rama y versionar el estado construido con fecha o digest.
- Hacer revisar las imágenes en busca de vulnerabilidades conocidas antes de desplegarlas y operar los contenedores sin permisos de root.
- Llevar un inventario de qué contenedores usan qué imagen.

## ¿Cómo ayuda PHP SOS en concreto?

- **Registrar el inventario:** revisamos todos los contenedores en ejecución, sus imágenes y versiones de PHP, también los contenedores auxiliares y los de preproducción.
- **Reconstruir y desplegar:** con el [servicio de parcheo de PHP](https://phpsos.de/es/leistungen/php-patch-service/) construimos las imágenes con la versión corregida y recreamos los contenedores de forma controlada.
- **Proteger la transición** cuando la actualización depende de la aplicación: valores de php.net, límite de memoria en el contenedor.
- **Vigilar de forma permanente:** con la [monitorización de seguridad](https://phpsos.de/es/leistungen/security-monitoring/) mantenemos a la vista los estados de las imágenes y el comportamiento llamativo de los contenedores.


## Preguntas frecuentes

**¿Basta con docker restart tras la actualización?**  
No. docker restart reinicia el contenedor con la misma imagen antigua. Debe construir o descargar la imagen nueva y recrear el contenedor a partir de ella, por ejemplo con docker compose up -d --force-recreate.

**¿Contiene ya la imagen oficial de PHP la versión corregida?**  
Lo mejor es comprobarlo directamente: descargue de nuevo la imagen y ejecute php -v en ella. Se esperan 8.5.12, 8.4.27, 8.3.36 u 8.2.35. Si la imagen muestra un número anterior, aún no está actualizada o procede de una caché.

**¿Está PHP en el contenedor menos expuesto que en el host?**  
La vulnerabilidad en sí actúa igual en el contenedor. Un contenedor bien construido puede limitar las consecuencias de una intrusión, por ejemplo con un usuario sin permisos de root y un sistema de archivos de solo lectura. Eso no sustituye al parche.

## Fuentes

- [php.net: avisos de seguridad](https://www.php.net/)
- [PHP 8 ChangeLog](https://www.php.net/ChangeLog-8.php)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
