# Rularea PHP în containere

> Rularea PHP în container: variante de imagini, php.ini de producție, extensii, limite de memorie, loguri și actualizări. Cu exemple și legătura cu PHP2Shell.

Sursa: https://phpsos.de/ro/php/php-in-containern/  
Stadiu: 25.10.2026  
Furnizor: PHP SOS, Asistență de urgență PHP și securitatea serverelor. Ajutor imediat pe WhatsApp: https://wa.me/491736494914?text=Bun%C4%83%20ziua%2C%20PHP%20SOS%2C%20avem%20nevoie%20de%20ajutor%20cu%20serverul%20nostru%20PHP.%20Firma%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Pe scurt:** Pentru a rula PHP în containere, alegeți varianta potrivită a imaginii oficiale (`fpm`, `apache` sau `cli`), activați php.ini de producție, instalați doar extensiile necesare și stabiliți limite de memorie și de procese care se potrivesc între ele. Containerele sunt imuabile: o actualizare de securitate PHP, precum cea pentru PHP2Shell, are efect abia după ce imaginea a fost reconstruită și fiecare container repornit. Această reconstrucție aparține de aceea, ca proces fix, oricărei exploatări în containere.

## De ce PHP în containere?

Containerele împachetează PHP, extensiile și configurația într-o imagine care rulează la fel pe orice server. Pentru companii, aceasta înseamnă: mai puține surprize între test și producție, restaurare mai rapidă și stări de versiune clare. Pentru securitate, însă, înseamnă și o obligație nouă: nimeni nu instalează automat actualizări într-un container.

Această pagină tratează exploatarea curentă. Cum corectați concret containerele existente împotriva PHP2Shell se găsește la [Aplicarea patch-urilor PHP în containere Docker](https://phpsos.de/ro/php2shell/docker-container-patchen/).

## Alegerea variantei potrivite de imagine

| Variantă | Conținut | Utilizare tipică |
|---|---|---|
| `php:<version>-fpm` | PHP-FPM, are nevoie de un server web în față | producție cu Nginx, Caddy sau un ingress |
| `php:<version>-apache` | Apache cu mod_php, implicit mpm_prefork | structuri simple, aplicații mai vechi |
| `php:<version>-cli` | linia de comandă, singura variantă care conține și php-cgi | cronjob-uri, workeri de cozi, pași de build |
| `…-alpine` | pe Alpine Linux, cu musl | imagini mici, la unele extensii sunt necesare adaptări |
| `…-bookworm`, `…-trixie` | pe versiunea Debian menționată | bază fixă pentru build-uri reproductibile |

Pentru proiecte noi se recomandă de regulă varianta `fpm` cu container de server web separat. La mod_php, echipa PHP vede în legătură cu PHP2Shell cel mai ridicat risc; cine folosește imaginea `apache` rulează tocmai acest mod de operare.

## Construirea unei imagini de producție

Un exemplu subțire pentru o aplicație cu acces MySQL:

```dockerfile
FROM php:8.4-fpm-alpine

# Activează configurația de producție (puternic recomandat conform documentației imaginii)
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

# Doar extensiile necesare
RUN docker-php-ext-install -j"$(nproc)" pdo_mysql

# Setări proprii
COPY zz-sicherheit.ini "$PHP_INI_DIR/conf.d/"

# Codul aparține lui root; workerii FPM rulează ca www-data și îl pot doar citi
COPY . /var/www/html
```

Scripturile auxiliare ale imaginii preiau construirea extensiilor: `docker-php-ext-configure` pentru opțiuni, `docker-php-ext-install` pentru construire, `docker-php-ext-enable` pentru activare, de exemplu după `pecl install`. Dacă se despachetează codul sursă cu `docker-php-source`, acesta trebuie, potrivit documentației, șters din nou în același strat. Fișierul `zz-sicherheit.ini` ar putea arăta așa:

```ini
expose_php = Off
display_errors = Off
log_errors = On
session.use_strict_mode = 1
session.cookie_httponly = 1
```

Alte două principii fac imaginile mai robuste. În primul rând, imaginea livrată conține doar ce este necesar la execuție; compilatorul, cache-urile de pachete și fișierele de test aparțin unei etape de build separate. În al doilea rând, utilizatorul sub care rulează PHP are voie să scrie doar acolo unde este necesar, de exemplu în directoarele de upload sau de cache de pe volume montate. Multe echipe rulează în plus containerul cu sistem de fișiere protejat la scriere. Un fișier PHP strecurat are atunci mult mai greu să rămână permanent, iar fiecare repornire restabilește starea curată a imaginii. Aceasta nu înlocuiește o investigație după un incident, dar reduce sensibil suprafața de atac.

## Procese, memorie și loguri în container

Trei șuruburi de reglaj stabilesc dacă un container PHP rulează stabil.

1. **Numărul de workeri:** `pm.max_children` din pool-ul FPM stabilește câte cereri sunt procesate simultan. Fiecare worker poate ocupa până la `memory_limit`.
2. **Limita de memorie a containerului:** ea limitează toate procesele împreună. Ca regulă aproximativă: numărul de workeri înmulțit cu memoria pe worker, plus o rezervă, trebuie să încapă sub limită, altfel sistemul încheie procese.
3. **Loguri:** containerele scriu logurile pe ieșirea standard. În PHP-FPM, `catch_workers_output = yes` redirecționează ieșirile workerilor în logul principal; fără această setare, ele se pierd, potrivit manualului, în neant.

Util este și `request_terminate_timeout`, care încheie cererile individuale după un interval, atunci când `max_execution_time` nu acționează. Cum rulați containerele într-un cluster descrie [Aplicarea patch-urilor PHP în Kubernetes](https://phpsos.de/ro/server/kubernetes/).

## Containere și securitate: ce a arătat PHP2Shell

La PHP2Shell, containerele joacă un rol dublu. Pe de o parte, sunt un ajutor: php.net recomandă ca măsură de tranziție la CVE-2026-109618 combinarea `memory_limit=-1` cu o limită de memorie prin container sau cgroup, ideal astfel încât să fie încheiat doar workerul afectat. `RLIMIT_AS` și `RLIMIT_DATA` sunt, potrivit php.net, nepotrivite pentru aceasta. Această măsură nu este o protecție completă și nu înlocuiește actualizarea.

Pe de altă parte, containerele sunt o capcană dacă imaginile nu sunt reconstruite. O imagine cu PHP 8.4.26 rămâne vulnerabilă, indiferent de câte ori repornește containerul. Abia o reconstruire la 8.4.27 sau mai nou și înlocuirea tuturor containerelor care rulează închid vulnerabilitatea. Starea poate fi controlată direct în containerul care rulează:

```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"));'
```

Dacă ultima comandă returnează `bool(false)`, PHP nu cunoaște directiva introdusă cu versiunile cu remediere; potrivit manualului, versiunea este atunci afectată. Pe termen lung ajută doar o reconstruire automată, așa cum este descrisă la [CI/CD: reconstruirea automată a imaginilor PHP](https://phpsos.de/ro/blog/php-images-in-ci-neu-bauen/).

> **Sfat:**
> Stabiliți în Dockerfile versiunea PHP exactă în tag și măriți-o în mod deliberat. Astfel, în cod se poate urmări când a fost distribuită ce versiune.

## Cum ajută PHP SOS concret?

În cadrul [securizării serverelor web PHP](https://phpsos.de/ro/leistungen/server-haertung/) ne ocupăm și de containere:

- **Verificarea imaginilor:** imaginea de bază, versiunea PHP, extensiile și configurația fiecărei imagini.
- **Întărirea configurației:** ini de producție, listă subțire de extensii, limite potrivite pentru workeri și memorie.
- **Configurarea reconstruirii:** un flux care reconstruiește și distribuie imaginile la lansările PHP noi.
- **Controlul mediului de execuție:** dovedim că în fiecare container care rulează funcționează versiunea corectată.


## Întrebări frecvente

**Care este varianta potrivită a imaginii PHP?**  
Pentru Nginx sau alt proxy, varianta fpm; pentru o structură simplă cu Apache, varianta apache; pentru scripturi și cronjob-uri, varianta cli. Variantele Alpine sunt mai mici, dar se bazează pe musl în loc de glibc, ceea ce se observă la unele extensii.

**Se actualizează PHP automat în container?**  
Nu. Un container care rulează nu se schimbă. Trebuie să reconstruiți imaginea cu noua versiune PHP și să reporniți containerele. Abia atunci rulează versiunea corectată.

**Cum se raportează memory_limit la limita containerului?**  
memory_limit limitează fiecare cerere PHP în parte, limita containerului întregul container. Ambele trebuie să se potrivească: numărul de workeri înmulțit cu memoria pe worker ar trebui să rămână sub limita containerului.

**Am nevoie de un php.ini în containere?**  
Da. Imaginile oficiale vin cu php.ini-development și php.ini-production ca șabloane. Pentru producție, documentația imaginii recomandă explicit șablonul de producție; setările proprii merg în conf.d.

## Surse

- [Docker Official Image: PHP](https://hub.docker.com/_/php)
- [Manualul PHP: configurarea FPM](https://www.php.net/manual/en/install.fpm.configuration.php)
- [php.net: anunț de securitate din 21.10.2026](https://www.php.net/)
