Situação atual: PHP2Shell. Duas vulnerabilidades críticas do PHP (CVSS 9,2) permitem executar código malicioso sem autenticação. Patches disponíveis desde 21/10/2026.O que fazer agora →

CI/CD: reconstruir imagens PHP automaticamente

Uma imagem desatualiza-se mesmo sem alterações ao código. Com builds agendados, uma verificação de versão e uma publicação por digest, os patches do PHP chegam de forma fiável à produção.

Atualizado em 6 min de leituraAlojamento e distribuições

Em resumo: Uma imagem Docker contém o PHP no estado do momento em que foi construída e desatualiza-se mesmo sem alterações ao código. Quem reconstrói as imagens automaticamente, de forma agendada e perante avisos de segurança, verifica a versão do PHP na pipeline e publica por digest, leva patches como o do PHP2Shell para a produção de forma planeável. Um build verde, por si só, não é comprovativo; conta a versão no contentor em execução.

Porque é que as imagens se desatualizam sem alterações ao código

Em muitas equipas, a pipeline de build só arranca quando alguém altera código. Para a aplicação, isso é lógico. Para a segurança, é um problema, porque o PHP na imagem provém da imagem base da tag do último build.

O PHP2Shell tornou isso visível. As versões corrigidas 8.5.12, 8.4.27, 8.3.36 e 8.2.35 surgiram a 21 de outubro de 2026. Um projeto em que ninguém trabalhou nesses dias não teve novo build e continuou a correr com o PHP antigo, embora a imagem base já tivesse sido atualizada há muito. O caminho manual para sair desta situação está descrito em Aplicar patches ao PHP em contentores Docker. Este artigo mostra como o automatizar.

Reconstruir imagens Docker automaticamente: três desencadeadores

Um processo robusto combina vários desencadeadores, para que nenhum tenha de sustentar tudo sozinho.

Desencadeador Implementação A ter em conta
Agendamento workflow agendado, p. ex. semanal recolhe patches também sem alterações ao código
Nova imagem base ferramenta que monitoriza imagens base e propõe alterações atua sobretudo em tags de versão fixas
Aviso de segurança arranque manual da pipeline pela equipa de operação precisa de um responsável claro

No GitHub Actions, o evento schedule trata do agendamento. Segundo a documentação do GitHub, usa a sintaxe cron com cinco campos, corre em UTC e apenas no branch padrão. As execuções agendadas podem arrancar com atraso em caso de carga elevada e, em repositórios públicos, o GitHub desativa-as após 60 dias sem atividade. Esta última situação afeta justamente os projetos calmos, ou seja, os que mais precisam da reconstrução automática.

Para o segundo desencadeador, o Dependabot suporta, segundo a documentação do GitHub, o ecossistema docker e propõe novos estados de imagens base como pull request. Convém conhecer duas limitações. Primeiro, alguém tem de verificar e integrar o pull request, caso contrário fica parado. Segundo, com uma tag de ramo como php:8.3-fpm, nada muda no Dockerfile quando a imagem base é reconstruída. Uma ferramenta que propõe alterações de texto não tem então nada a propor. É precisamente por isso que é necessária também a reconstrução agendada.

O terceiro desencadeador parece banal, mas na prática falha muitas vezes na questão de quem o aciona. Defina quem acompanha os avisos de segurança do PHP e quem pode iniciar a pipeline, também ao fim de semana. No PHP2Shell, entre o pré-aviso e o patch passou apenas um dia.

Uma pipeline que apanha o PHP desatualizado

O exemplo seguinte para GitHub Actions constrói a imagem semanalmente e sob comando, verifica a versão do PHP e interrompe se estiver abaixo do estado corrigido. Adapte o registo, os nomes e a versão mínima.

name: php-image-rebuild
on:
  schedule:
    - cron: "0 3 * * 1"      # às segundas-feiras às 03:00 UTC
  workflow_dispatch: {}      # arranque manual perante avisos de segurança

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);'

A verificação de versão funciona com imagens PHP oficiais, cujo número de versão indica o estado real. Se a sua imagem usa pacotes PHP de uma distribuição, o número mantém-se muitas vezes igual após um backport. Nesse caso, em vez do número, verifique o changelog do pacote quanto aos números CVE, como descrito no artigo Comprovar números CVE no changelog do pacote.

Depois da verificação, seguem-se na prática mais três passos: analisar a imagem quanto a vulnerabilidades conhecidas, enviá-la para o registo com data e digest e passar o digest à implementação. Que tags e variantes são adequadas como base é explicado em Imagens Docker oficiais do PHP.

Do build ao contentor em execução

O erro de raciocínio mais frequente: a pipeline está verde, logo está tudo com patch. Na realidade, a nova imagem está apenas no registo. O patch só entra em vigor quando cada contentor tiver sido recriado a partir da nova imagem.

  1. Publicar por digest: a implementação referencia o digest da nova imagem, não uma tag que se desloca.
  2. Primeiro staging, depois produção: testes automáticos numa cópia detetam falhas causadas por novas imagens base.
  3. Verificar em operação: depois da publicação, executar php -v no contentor em execução e comparar o digest com o do build.
  4. Limitar o caminho de volta: a imagem antiga fica disponível por pouco tempo para um regresso, mas contém o PHP vulnerável.

No Kubernetes aplicam-se regras próprias, por exemplo sobre a pull policy; estão em Aplicar patches ao PHP no Kubernetes.

Lacunas típicas na cadeia

  • Cache de build no runner: sem --pull e --no-cache, a imagem base antiga é reutilizada.
  • Espelho de registo: uma cache interna ainda entrega o estado antigo da imagem base.
  • Builds de várias fases: conta a versão do PHP da última fase, mas muitas vezes só se verifica a primeira.
  • Imagens secundárias: workers de filas, contentores cron e ferramentas internas têm pipelines próprias ou nenhuma.
  • Digests fixados: um digest da imagem base uma vez fixado nunca é atualizado se nenhuma ferramenta o monitorizar.
Importante

Uma reconstrução substitui o PHP, não os dados. O código malicioso que chegou antes do patch a volumes, pastas de upload ou à base de dados permanece e tem de ser verificado em separado.

Quem reage quando a reconstrução falha?

Uma reconstrução automática vale tanto quanto a reação à sua falha. Se a verificação de versão dispara ou o build é interrompido por causa de uma imagem base alterada, alguém tem de reparar. Em muitas equipas, essas mensagens acabam numa caixa de correio que ninguém lê ou num canal em que builds vermelhos há muito são rotina.

Resultou bem uma regra clara: uma reconstrução de segurança falhada é um ticket com responsável e prazo, não um aviso entre muitos. Registe além disso, para cada imagem publicada, a data, o digest e a versão do PHP verificada. Esta lista responde, no próximo aviso, em minutos, a que aplicações dizem respeito, e serve perante auditores ou seguradoras como comprovativo. Como daqui resulta um procedimento duradouro está descrito em Gestão de patches como processo em vez de bombeiros.

Como ajuda concretamente a PHP SOS?

  • Verificar pipelines: analisamos as suas cadeias de build e de publicação e mostramos onde um patch pode ficar retido.
  • Automatizar a reconstrução: configuramos builds agendados, verificação de versão e publicação por digest.
  • Registar todas as imagens: associamos a cada contentor em execução a sua pipeline, também imagens secundárias e antigas.
  • Acompanhar de forma duradoura: no contrato de manutenção de segurança, acompanhamos avisos de segurança e desencadeamos reconstruções.

Perguntas frequentes

Com que frequência se deve reconstruir uma imagem PHP?

Não há um número fixo. Resultou bem um build agendado regular, por exemplo semanal, mais um build imediato perante avisos de segurança. O decisivo é que um novo patch não tenha de esperar pela próxima alteração de código.

Um build bem-sucedido basta como comprovativo?

Não. Um build prova apenas que existe uma nova imagem. Só quando os contentores em execução forem recriados a partir dessa imagem e o php -v nela mostrar a versão corrigida é que o patch está em vigor.

Porque é que, apesar da reconstrução, aparece a versão antiga do PHP?

Causas frequentes são uma cache de build que reutiliza a imagem base antiga, um espelho de registo com estado antigo ou uma segunda linha FROM num build de várias fases. Construa com --pull e --no-cache e verifique cada fase.

O Dependabot pode atualizar imagens base?

Segundo a documentação do GitHub, o Dependabot suporta o ecossistema Docker para atualizações de versão e de segurança. Propõe alterações às imagens base como pull request. Isso não substitui a reconstrução quando a tag se mantém.

Fontes

Contacto imediato

Cada hora conta. Escreva-nos agora.

Descreva brevemente o sistema, a versão do PHP e o que observou. Entramos em contacto consigo, esclarecemos a situação e trabalhamos remotamente até o incidente estar concluído e documentado.

Ajuda imediata