Situación actual: PHP2Shell. Dos vulnerabilidades críticas de PHP (CVSS 9.2) permiten ejecutar código malicioso sin autenticación. Parches desde el 21/10/2026.Qué hacer ahora →

CI/CD: reconstruir automáticamente las imágenes de PHP

Una imagen se queda obsoleta aunque no cambie el código. Con builds programados, una comprobación de versión y un despliegue por digest, los parches de PHP llegan a producción de forma fiable.

Actualizado 6 min de lecturaHosting y distribuciones

En resumen: Una imagen Docker contiene PHP en el nivel de su momento de construcción y se queda obsoleta aunque no cambie el código. Quien reconstruye las imágenes automáticamente, de forma programada y ante avisos de seguridad, comprueba la versión de PHP en el pipeline y la despliega por digest, lleva a producción de forma planificable parches como el de PHP2Shell. Un build en verde no es por sí solo un justificante; cuenta la versión del contenedor en ejecución.

Por qué las imágenes se quedan obsoletas sin cambios de código

En muchos equipos, el pipeline de build solo arranca cuando alguien cambia código. Para la aplicación es lógico. Para la seguridad es un problema, porque el PHP de la imagen procede de la imagen base del tag del último build.

PHP2Shell lo ha hecho visible. Las versiones corregidas 8.5.12, 8.4.27, 8.3.36 y 8.2.35 aparecieron el 21 de octubre de 2026. Un proyecto en el que nadie trabajó en esos días no recibió ningún build nuevo y siguió funcionando con el PHP antiguo, aunque la imagen base hacía tiempo que estaba actualizada. El camino manual para salir de esta situación lo describe Parchear PHP en contenedores Docker. Este artículo muestra cómo automatizarlo.

Reconstruir imágenes Docker automáticamente: tres desencadenantes

Un proceso robusto combina varios desencadenantes, para que ninguno tenga que sostenerlo solo.

Desencadenante Implementación A tener en cuenta
Programación workflow programado, p. ej. semanal recoge los parches aunque no cambie el código
Imagen base nueva herramienta que vigila las imágenes base y propone cambios actúa sobre todo con tags de versión fijos
Aviso de seguridad arranque manual del pipeline por el equipo de operaciones necesita un responsable claro

En GitHub Actions, el evento schedule se encarga de la programación. Según la documentación de GitHub, usa la sintaxis cron de cinco campos, se ejecuta en UTC y solo en la rama predeterminada. Las ejecuciones programadas pueden arrancar con retraso si hay mucha carga, y en repositorios públicos GitHub las desactiva tras 60 días sin actividad. Esto último afecta justo a los proyectos tranquilos, es decir, a los que más necesitan la reconstrucción automática.

Para el segundo desencadenante, Dependabot admite, según la documentación de GitHub, el ecosistema docker y propone niveles nuevos de imágenes base como pull request. Conviene conocer dos limitaciones. Primero, alguien debe revisar y fusionar el pull request; de lo contrario, queda sin atender. Segundo, con un tag de rama como php:8.3-fpm no cambia nada en el Dockerfile cuando se reconstruye la imagen base. Una herramienta que propone cambios de texto no tiene entonces nada que proponer. Precisamente por eso hace falta además la reconstrucción programada.

El tercer desencadenante suena banal, pero en la práctica suele fallar por la pregunta de quién lo activa. Decida quién sigue los avisos de seguridad sobre PHP y quién puede arrancar el pipeline, también en fin de semana. Con PHP2Shell, entre el preaviso y el parche pasó solo un día.

Un pipeline que detecta PHP obsoleto

El siguiente ejemplo para GitHub Actions construye la imagen semanalmente y a petición, comprueba la versión de PHP y aborta si está por debajo del nivel corregido. Adapte el registro, los nombres y la versión mínima.

name: php-image-rebuild
on:
  schedule:
    - cron: "0 3 * * 1"      # lunes a las 03:00 UTC
  workflow_dispatch: {}      # arranque manual ante avisos de seguridad

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Image ohne Cache und mit frischem Basis-Image bauen
        run: docker build --pull --no-cache -t app:${{ github.run_id }} .
      - name: PHP-Version prüfen (Mindeststand des Zweigs 8.3)
        run: |
          docker run --rm app:${{ github.run_id }} php -v
          docker run --rm app:${{ github.run_id }} \
            php -r 'exit(version_compare(PHP_VERSION, "8.3.36", ">=") ? 0 : 1);'

La comprobación de versión funciona con imágenes oficiales de PHP, cuyo número de versión indica el nivel real. Si su imagen usa paquetes de PHP de una distribución, el número suele permanecer igual tras un backport. Entonces compruebe, en lugar del número, el registro de cambios del paquete en busca de los números CVE, como se describe en el artículo Acreditar números CVE en el registro de cambios del paquete.

Tras la comprobación, en la práctica siguen tres pasos más: escanear la imagen en busca de vulnerabilidades conocidas, subirla al registro con fecha y digest y pasar el digest al despliegue. Qué tags y variantes sirven como base lo explica Imágenes Docker oficiales de PHP.

Del build al contenedor en ejecución

El error de razonamiento más frecuente: el pipeline está en verde, luego todo está parcheado. En realidad, la imagen nueva solo está en el registro. El parche se hace efectivo solo cuando cada contenedor se ha recreado a partir de la imagen nueva.

  1. Desplegar por digest: el despliegue hace referencia al digest de la imagen nueva, no a un tag que se mueve.
  2. Primero staging, luego producción: las pruebas automáticas en una copia detectan roturas causadas por imágenes base nuevas.
  3. Comprobar en explotación: tras el despliegue, ejecutar php -v en el contenedor en ejecución y comparar el digest con el build.
  4. Limitar el retorno: la imagen antigua sigue disponible para un breve retorno, pero contiene el PHP vulnerable.

En Kubernetes rigen reglas propias, por ejemplo sobre la política de descarga; figuran en Parchear PHP en Kubernetes.

Lagunas típicas en la cadena

  • Caché de build en el runner: sin --pull y --no-cache se reutiliza la imagen base antigua.
  • Espejo de registro: una caché intermedia interna sigue sirviendo el nivel antiguo de la imagen base.
  • Builds de varias etapas: cuenta la versión de PHP de la última etapa, pero a menudo solo se comprueba la primera.
  • Imágenes secundarias: los workers de colas, los contenedores cron y las herramientas internas tienen pipelines propios o ninguno.
  • Digests fijados: un digest de la imagen base, una vez fijado, nunca se actualiza si ninguna herramienta lo vigila.
Importante

Una reconstrucción sustituye PHP, no los datos. El código malicioso que haya llegado antes del parche a volúmenes, carpetas de subida o la base de datos permanece y debe revisarse por separado.

¿Quién reacciona cuando la reconstrucción falla?

Una reconstrucción automática es tan buena como la reacción ante su fallo. Si la comprobación de versión salta o el build se aborta por una imagen base modificada, alguien tiene que darse cuenta. En muchos equipos, estos avisos acaban en un buzón que nadie lee o en un canal en el que los builds en rojo son ya cosa de todos los días.

Ha dado buen resultado una regla clara: una reconstrucción de seguridad fallida es un ticket con responsable y plazo, no un aviso entre muchos. Anote además para cada imagen desplegada la fecha, el digest y la versión de PHP comprobada. Esta lista responde en minutos, ante el siguiente aviso, qué aplicaciones están afectadas, y sirve como justificante ante auditores o aseguradoras. Cómo de ello surge un procedimiento permanente lo describe Gestión de parches como proceso en lugar de bomberos.

¿Cómo ayuda PHP SOS en concreto?

  • Revisar pipelines: examinamos sus cadenas de build y despliegue y mostramos dónde puede quedarse atascado un parche.
  • Automatizar la reconstrucción: configuramos builds programados, comprobación de versión y despliegue por digest.
  • Registrar todas las imágenes: asignamos a cada contenedor en ejecución su pipeline, también las imágenes secundarias y antiguas.
  • Atender de forma permanente: en el contrato de mantenimiento de seguridad seguimos los avisos de seguridad y lanzamos las reconstrucciones.

Preguntas frecuentes

¿Con qué frecuencia debe reconstruirse una imagen de PHP?

No hay una cifra fija. Ha dado buen resultado un build programado regular, por ejemplo semanal, más un build inmediato ante avisos de seguridad. Lo decisivo es que un parche nuevo no tenga que esperar al siguiente cambio de código.

¿Basta un build correcto como justificante?

No. Un build solo prueba que existe una imagen nueva. Solo cuando los contenedores en ejecución se han recreado a partir de esa imagen y php -v muestra en ellos la versión corregida, el parche es efectivo.

¿Por qué sigue apareciendo la versión antigua de PHP tras la reconstrucción?

Causas frecuentes son una caché de build que reutiliza la imagen base antigua, un espejo de registro con un nivel antiguo o una segunda línea FROM en un build de varias etapas. Construya con --pull y --no-cache y revise cada etapa.

¿Puede Dependabot actualizar imágenes base?

Según la documentación de GitHub, Dependabot admite el ecosistema Docker para actualizaciones de versión y de seguridad. Propone cambios en imágenes base como pull request. No sustituye la reconstrucción cuando el tag permanece igual.

Fuentes

Contacto inmediato

Cada hora cuenta. Escríbanos ahora.

Describa brevemente el sistema, la versión de PHP y lo que ha observado. Nos pondremos en contacto, aclararemos la situación y trabajaremos en remoto hasta que el incidente quede cerrado y documentado.

Ayuda inmediata