# Operar PHP em contentores

> Operar PHP em contentores: variantes de imagem, php.ini de produção, extensões, limites de memória, registos e atualizações. Com exemplos e ligação ao PHP2Shell.

Fonte: https://phpsos.de/pt/php/php-in-containern/  
Atualizado em: 25/10/2026  
Prestador: PHP SOS, Assistência de emergência PHP e segurança de servidores. Ajuda imediata por WhatsApp: https://wa.me/491736494914?text=Ol%C3%A1%2C%20PHP%20SOS%2C%20precisamos%20de%20ajuda%20com%20o%20nosso%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Em resumo:** Para operar PHP em contentores, escolha a variante adequada da imagem oficial (`fpm`, `apache` ou `cli`), ative o php.ini de produção, instale apenas as extensões necessárias e defina limites de memória e de processos que sejam coerentes entre si. Os contentores são imutáveis: uma atualização de segurança do PHP, como a do PHP2Shell, só produz efeito quando a imagem é reconstruída e cada contentor reiniciado. Esta reconstrução pertence, por isso, como processo fixo, a qualquer operação com contentores.

## Porquê PHP em contentores?

Os contentores empacotam o PHP, as extensões e a configuração numa imagem que corre da mesma forma em qualquer servidor. Para as empresas, isto significa: menos surpresas entre teste e produção, recuperação mais rápida e estados de versão claros. Para a segurança significa, porém, também um novo dever: ninguém aplica automaticamente atualizações dentro de um contentor.

Esta página trata da operação corrente. Como aplicar concretamente o patch do PHP2Shell a contentores existentes está em [Aplicar o patch do PHP em contentores Docker](https://phpsos.de/pt/php2shell/docker-container-patchen/).

## Escolher a variante de imagem certa

| Variante | Conteúdo | Utilização típica |
|---|---|---|
| `php:<version>-fpm` | PHP-FPM, precisa de um servidor web à frente | produção com Nginx, Caddy ou um ingress |
| `php:<version>-apache` | Apache com mod_php, por predefinição mpm_prefork | estruturas simples, aplicações mais antigas |
| `php:<version>-cli` | linha de comandos, é a única variante que contém também o php-cgi | cronjobs, queue workers, passos de build |
| `…-alpine` | em Alpine Linux com musl | imagens pequenas, em algumas extensões são necessários ajustes |
| `…-bookworm`, `…-trixie` | na versão Debian indicada | base fixa para builds reproduzíveis |

Para projetos novos recomenda-se, em regra, a variante `fpm` com um contentor de servidor web separado. No mod_php, a equipa do PHP vê, no contexto do PHP2Shell, o risco mais elevado; quem usa a imagem `apache` opera precisamente esse modo de operação.

## Construir uma imagem de produção

Um exemplo enxuto para uma aplicação com acesso MySQL:

```dockerfile
FROM php:8.4-fpm-alpine

# Ativar a configuração de produção (muito recomendado pela documentação da imagem)
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

# Apenas as extensões necessárias
RUN docker-php-ext-install -j"$(nproc)" pdo_mysql

# Definições próprias
COPY zz-sicherheit.ini "$PHP_INI_DIR/conf.d/"

# O código pertence ao root; os workers FPM correm como www-data e só o podem ler
COPY . /var/www/html
```

Os scripts auxiliares da imagem tratam da construção das extensões: `docker-php-ext-configure` para opções, `docker-php-ext-install` para construir, `docker-php-ext-enable` para ativar, por exemplo após `pecl install`. Se o código-fonte for extraído com `docker-php-source`, deve, segundo a documentação, ser apagado de novo na mesma camada. O ficheiro `zz-sicherheit.ini` poderia ter este aspeto:

```ini
expose_php = Off
display_errors = Off
log_errors = On
session.use_strict_mode = 1
session.cookie_httponly = 1
```

Dois outros princípios tornam as imagens mais robustas. Primeiro, a imagem entregue contém apenas o que é preciso em tempo de execução; compiladores, caches de pacotes e ficheiros de teste pertencem a uma fase de build própria. Segundo, o utilizador com que o PHP corre só pode escrever onde é necessário, por exemplo em diretórios de uploads ou de cache em volumes montados. Muitas equipas operam além disso o contentor com o sistema de ficheiros protegido contra escrita. Um ficheiro PHP introduzido tem então muito mais dificuldade em permanecer, e cada reinício repõe o estado limpo da imagem. Isto não substitui uma investigação após um incidente, mas reduz sensivelmente a superfície de ataque.

## Processos, memória e registos no contentor

Três parâmetros determinam se um contentor PHP corre de forma estável.

1. **Número de workers:** o `pm.max_children` no pool FPM define quantos pedidos são tratados em simultâneo. Cada worker pode ocupar até ao `memory_limit`.
2. **Limite de memória do contentor:** limita todos os processos em conjunto. Como regra aproximada: o número de workers vezes a memória por worker, mais uma reserva, tem de caber abaixo do limite, caso contrário o sistema termina processos.
3. **Registos:** os contentores escrevem registos na saída padrão. No PHP-FPM, `catch_workers_output = yes` encaminha as saídas dos workers para o registo principal; sem esta definição perdem-se, segundo o manual, no vazio.

É ainda útil o `request_terminate_timeout`, que termina pedidos individuais após um período, quando o `max_execution_time` não atua. Como operar contentores no cluster descreve-o [Aplicar o patch do PHP no Kubernetes](https://phpsos.de/pt/server/kubernetes/).

## Contentores e segurança: o que o PHP2Shell mostrou

No PHP2Shell, os contentores desempenham um papel duplo. Por um lado, são uma ajuda: o php.net recomenda, como medida provisória para a CVE-2026-109618, combinar `memory_limit=-1` com um limite de memória por contentor ou cgroup, idealmente de modo a que apenas o worker afetado seja terminado. `RLIMIT_AS` e `RLIMIT_DATA` não são adequados para isso, segundo o php.net. Esta medida não é uma proteção completa e não substitui a atualização.

Por outro lado, os contentores são uma armadilha quando as imagens não são reconstruídas. Uma imagem com o PHP 8.4.26 continua vulnerável, por mais vezes que o contentor reinicie. Só uma reconstrução para o 8.4.27 ou posterior e a substituição de todos os contentores em execução fecham a vulnerabilidade. O estado pode ser verificado diretamente no contentor em execução:

```bash
docker exec <container> php -v
docker exec <container> php-fpm -v
docker exec <container> php -r 'var_dump(ini_get("memory_hard_limit_percent"));'
```

Se o último comando devolver `bool(false)`, o PHP não conhece a diretiva introduzida com as versões corrigidas; segundo o manual, a versão está então afetada. A longo prazo, só ajuda uma reconstrução automática, como descrito em [CI/CD: reconstruir imagens PHP automaticamente](https://phpsos.de/pt/blog/php-images-in-ci-neu-bauen/).

> **Dica:**
> Defina no Dockerfile a versão exata do PHP na tag e aumente-a de forma deliberada. Assim, fica rastreável no código quando foi distribuída cada versão.

## Como ajuda concretamente o PHP SOS?

No [hardening de servidores web PHP](https://phpsos.de/pt/leistungen/server-haertung/), tratamos também dos contentores:

- **Verificar imagens:** imagem base, versão do PHP, extensões e configuração de cada imagem.
- **Reforçar a configuração:** ini de produção, lista de extensões enxuta, limites de workers e de memória adequados.
- **Configurar a reconstrução:** um processo que reconstrói e distribui as imagens a cada nova versão do PHP.
- **Controlar o tempo de execução:** comprovamos que em cada contentor em execução corre a versão corrigida.


## Perguntas frequentes

**Que variante da imagem PHP é a certa?**  
Para o Nginx ou outro proxy, a variante fpm; para uma estrutura simples com Apache, a variante apache; para scripts e cronjobs, a variante cli. As variantes Alpine são mais pequenas, mas assentam em musl em vez de glibc, o que se nota em algumas extensões.

**O PHP em contentores é atualizado automaticamente?**  
Não. Um contentor em execução não muda. Tem de reconstruir a imagem com a nova versão do PHP e reiniciar os contentores. Só então corre a versão corrigida.

**Como se relacionam o memory_limit e o limite do contentor?**  
O memory_limit limita cada pedido PHP individual, o limite do contentor limita o contentor inteiro. Ambos têm de ser coerentes: o número de workers vezes a memória por worker deve ficar abaixo do limite do contentor.

**Preciso de um php.ini em contentores?**  
Sim. As imagens oficiais trazem o php.ini-development e o php.ini-production como modelos. Para produção, a documentação da imagem recomenda expressamente o modelo de produção; as definições próprias vão para o conf.d.

## Fontes

- [Docker Official Image: PHP](https://hub.docker.com/_/php)
- [Manual do PHP: configuração do FPM](https://www.php.net/manual/en/install.fpm.configuration.php)
- [php.net: aviso de segurança de 21/10/2026](https://www.php.net/)
