# PHP:n ajaminen konteissa

> PHP:n ajaminen kontissa: kuvavariantit, tuotanto-php.ini, laajennukset, muistirajat, lokit ja päivitykset. Esimerkein ja PHP2Shell-yhteydellä.

Lähde: https://phpsos.de/fi/php/php-in-containern/  
Tilanne: 25.10.2026  
Palveluntarjoaja: PHP SOS, PHP-hätäapu ja palvelimen tietoturva. Pikaapu WhatsAppilla: https://wa.me/491736494914?text=Hei%20PHP%20SOS%2C%20tarvitsemme%20apua%20PHP-palvelimemme%20kanssa.%20Yritys%3A%20%E2%80%A6%20Verkkosivusto%3A%20%E2%80%A6

**Lyhyesti:** PHP:n ajamiseksi konteissa valitaan virallisen kuvan sopiva variantti (`fpm`, `apache` tai `cli`), otetaan käyttöön tuotanto-php.ini, asennetaan vain tarvittavat laajennukset ja asetetaan toisiinsa sopivat muisti- ja prosessirajat. Kontit ovat muuttumattomia: PHP:n tietoturvapäivitys, kuten PHP2Shellin kohdalla, tehoaa vasta, kun kuva on rakennettu uudelleen ja jokainen kontti käynnistetty uudelleen. Tämä uudelleenrakennus kuuluu siksi kiinteänä prosessina jokaiseen konttikäyttöön.

## Miksi PHP konteissa?

Kontit pakkaavat PHP:n, laajennukset ja konfiguraation kuvaan, joka toimii jokaisella palvelimella samoin. Yrityksille se tarkoittaa: vähemmän yllätyksiä testin ja tuotannon välillä, nopeampi palautus ja selkeät versiotilanteet. Tietoturvan kannalta se tarkoittaa kuitenkin myös uutta velvoitetta: kontissa kukaan ei asenna päivityksiä automaattisesti.

Tämä sivu käsittelee käynnissä olevaa käyttöä. Miten olemassa olevat kontit korjataan konkreettisesti PHP2Shelliä vastaan, kerrotaan sivulla [PHP:n korjaus Docker-konteissa](https://phpsos.de/fi/php2shell/docker-container-patchen/).

## Oikean kuvavariantin valinta

| Variantti | Sisältö | Tyypillinen käyttö |
|---|---|---|
| `php:<version>-fpm` | PHP-FPM, tarvitsee edellä olevan verkkopalvelimen | tuotanto Nginxin, Caddyn tai ingressin kanssa |
| `php:<version>-apache` | Apache mod_php:n kanssa, oletuksena mpm_prefork | yksinkertaiset rakenteet, vanhemmat sovellukset |
| `php:<version>-cli` | komentorivi, sisältää ainoana varianttina myös php-cgi:n | cron-työt, jonotyöntekijät, rakennusvaiheet |
| `…-alpine` | Alpine Linuxin päällä muslilla | pienet kuvat, joillakin laajennuksilla tarvitaan mukautuksia |
| `…-bookworm`, `…-trixie` | mainitun Debian-version päällä | kiinteä perusta toistettaville rakennuksille |

Uusille hankkeille suositellaan yleensä `fpm`-varianttia erillisellä verkkopalvelinkontilla. mod_php:n kohdalla PHP-tiimi näkee PHP2Shellin yhteydessä suurimman riskin; `apache`-kuvaa käyttävä ajaa juuri tätä ajotapaa.

## Tuotantokuvan rakentaminen

Kevyt esimerkki sovellukselle, jolla on MySQL-yhteys:

```dockerfile
FROM php:8.4-fpm-alpine

# Ota tuotantokonfiguraatio käyttöön (kuvan dokumentaation mukaan ehdottomasti suositeltu)
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

# Vain tarvittavat laajennukset
RUN docker-php-ext-install -j"$(nproc)" pdo_mysql

# Omat asetukset
COPY zz-sicherheit.ini "$PHP_INI_DIR/conf.d/"

# Koodi kuuluu rootille; FPM-workerit toimivat käyttäjänä www-data ja voivat vain lukea sen
COPY . /var/www/html
```

Kuvan apukomentosarjat hoitavat laajennusten rakentamisen: `docker-php-ext-configure` valitsimille, `docker-php-ext-install` rakentamiseen, `docker-php-ext-enable` käyttöönottoon, esimerkiksi komennon `pecl install` jälkeen. Jos lähdekoodi puretaan komennolla `docker-php-source`, se pitäisi dokumentaation mukaan poistaa samassa kerroksessa. Tiedosto `zz-sicherheit.ini` voisi näyttää tältä:

```ini
expose_php = Off
display_errors = Off
log_errors = On
session.use_strict_mode = 1
session.cookie_httponly = 1
```

Kaksi muuta perusperiaatetta tekee kuvista kestävämpiä. Ensinnäkin toimitettu kuva sisältää vain sen, mitä ajon aikana tarvitaan; kääntäjät, pakettivälimuistit ja testitiedostot kuuluvat omaan rakennusvaiheeseensa. Toiseksi käyttäjä, jonka alla PHP toimii, saa kirjoittaa vain siellä, missä se on välttämätöntä, esimerkiksi liitetyillä volyymeilla olevissa lataus- tai välimuistihakemistoissa. Monet tiimit ajavat konttia lisäksi kirjoitussuojatulla tiedostojärjestelmällä. Sisään livahtaneen PHP-tiedoston on silloin selvästi vaikeampaa pysyä pysyvästi, ja jokainen uudelleenkäynnistys palauttaa kuvan puhtaan tilan. Se ei korvaa tutkintaa poikkeaman jälkeen mutta pienentää hyökkäyspintaa tuntuvasti.

## Prosessit, muisti ja lokit kontissa

Kolme säätöruuvia ratkaisee, toimiiko PHP-kontti vakaasti.

1. **Workerien määrä:** FPM-poolin `pm.max_children` määrää, montako pyyntöä käsitellään samanaikaisesti. Jokainen worker voi varata enintään `memory_limit`-arvon verran.
2. **Kontin muistiraja:** Se rajoittaa kaikkia prosesseja yhteensä. Karkea sääntö: workerien määrä kertaa kunkin workerin muisti plus varanto on mahduttava rajan alle, muuten järjestelmä päättää prosesseja.
3. **Lokit:** Kontit kirjoittavat lokit vakiotulosteeseen. PHP-FPM:ssä `catch_workers_output = yes` ohjaa workerien tulosteet pääloki-in; ilman asetusta ne katoavat käsikirjan mukaan tyhjiin.

Hyödyllinen on myös `request_terminate_timeout`, joka päättää yksittäisiä pyyntöjä tietyn ajan jälkeen, kun `max_execution_time` ei tehoa. Miten konttien ajaminen klusterissa tapahtuu, kuvaa [PHP:n korjaus Kubernetesissa](https://phpsos.de/fi/server/kubernetes/).

## Kontit ja tietoturva: mitä PHP2Shell on osoittanut

PHP2Shellissä konteilla on kaksoisrooli. Toisaalta ne auttavat: php.net suosittelee väliaikaisena toimenpiteenä haavoittuvuuteen CVE-2026-109618 yhdistämään `memory_limit=-1` kontin tai cgroupin kautta asetettuun muistirajaan, mieluiten niin, että vain kyseinen worker päätetään. `RLIMIT_AS` ja `RLIMIT_DATA` ovat siihen php.netin mukaan sopimattomia. Tämä toimenpide ei ole täydellinen suoja eikä korvaa päivitystä.

Toisaalta kontit ovat ansa, jos kuvia ei rakenneta uudelleen. Kuva, jossa on PHP 8.4.26, pysyy haavoittuvana riippumatta siitä, kuinka usein kontti käynnistyy uudelleen. Vasta uudelleenrakennus versioon 8.4.27 tai uudempaan ja kaikkien käynnissä olevien konttien vaihto sulkevat aukon. Tilan voi tarkistaa suoraan käynnissä olevasta kontista:

```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"));'
```

Jos viimeinen komento palauttaa `bool(false)`, PHP ei tunne korjausversioiden mukana tullutta direktiiviä; käsikirjan mukaan versio on silloin haavoittuva. Pysyvästi auttaa vain automaattinen uudelleenrakennus, kuten kohdassa [CI/CD: PHP-kuvien automaattinen uudelleenrakennus](https://phpsos.de/fi/blog/php-images-in-ci-neu-bauen/) kuvataan.

> **Vinkki:**
> Määrittäkää Dockerfilessä tarkka PHP-versio tunnisteessa ja nostakaa sitä tietoisesti. Näin koodista on jäljitettävissä, milloin mikäkin versio on otettu käyttöön.

## Miten PHP SOS auttaa konkreettisesti?

[PHP-verkkopalvelinten koventamisessa](https://phpsos.de/fi/leistungen/server-haertung/) huolehdimme myös konteista:

- **Kuvien tarkistus:** Jokaisen kuvan perus-kuva, PHP-versio, laajennukset ja konfiguraatio.
- **Konfiguraation koventaminen:** Tuotanto-ini, kevyt laajennuslista, sopivat worker- ja muistirajat.
- **Uudelleenrakennuksen käyttöönotto:** Kulku, joka rakentaa kuvat uudelleen ja ottaa ne käyttöön uusien PHP-julkaisujen yhteydessä.
- **Ajonaikainen valvonta:** Osoitamme, että jokaisessa käynnissä olevassa kontissa on korjattu versio.


## Usein kysytyt kysymykset

**Mikä PHP-kuvan variantti on oikea?**  
Nginxille tai muulle välityspalvelimelle fpm-variantti, yksinkertaiseen Apache-rakenteeseen apache-variantti, komentosarjoihin ja cron-töihin cli-variantti. Alpine-variantit ovat pienempiä mutta perustuvat muslin eikä glibcin päälle, mikä näkyy joissakin laajennuksissa.

**Päivittyykö PHP kontissa automaattisesti?**  
Ei päivity. Käynnissä oleva kontti ei muutu. Kuva on rakennettava uudelleen uudella PHP-versiolla ja kontit käynnistettävä uudelleen. Vasta sitten korjattu versio on käytössä.

**Miten memory_limit ja kontin raja suhtautuvat toisiinsa?**  
memory_limit rajoittaa jokaista yksittäistä PHP-pyyntöä, kontin raja koko konttia. Molempien on sovittava yhteen: workerien määrä kertaa kunkin workerin muisti pitäisi olla kontin rajan alapuolella.

**Tarvitsenko konteissa php.ini-tiedoston?**  
Tarvitset. Viralliset kuvat sisältävät pohjat php.ini-development ja php.ini-production. Tuotantoon kuvan dokumentaatio suosittelee nimenomaisesti tuotantopohjaa; omat asetukset menevät hakemistoon conf.d.

## Lähteet

- [Docker Official Image: PHP](https://hub.docker.com/_/php)
- [PHP-käsikirja: FPM-konfiguraatio](https://www.php.net/manual/en/install.fpm.configuration.php)
- [php.net: tietoturvailmoitus 21.10.2026](https://www.php.net/)
