# Kør PHP i containere

> Kør PHP i container: image-varianter, produktions-php.ini, udvidelser, hukommelsesgrænser, logs og opdateringer. Med eksempler og sammenhæng med PHP2Shell.

Kilde: https://phpsos.de/da/php/php-in-containern/  
Status: 25.10.2026  
Udbyder: PHP SOS, PHP-nødhjælp og serversikkerhed. Akut hjælp på WhatsApp: https://wa.me/491736494914?text=Hej%20PHP%20SOS%2C%20vi%20har%20brug%20for%20hj%C3%A6lp%20med%20vores%20PHP-server.%20Firma%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kort sagt:** For at køre PHP i containere vælger I den passende variant af det officielle image (`fpm`, `apache` eller `cli`), aktiverer produktions-php.ini, installerer kun nødvendige udvidelser og sætter hukommelses- og procesgrænser, der passer sammen. Containere er uforanderlige: En PHP-sikkerhedsopdatering som den til PHP2Shell virker først, når imaget er bygget på ny, og hver container er genstartet. Dette nybyg hører derfor som en fast proces med i enhver containerdrift.

## Hvorfor PHP i containere?

Containere pakker PHP, udvidelser og konfiguration ind i et image, der kører ens på hver server. For virksomheder betyder det: færre overraskelser mellem test og produktion, hurtigere genopretning og klare versionsstatusser. For sikkerheden betyder det dog også en ny forpligtelse: Ingen indspiller automatisk opdateringer i en container.

Denne side behandler den løbende drift. Hvordan I konkret patcher eksisterende containere mod PHP2Shell, står under [Patch PHP i Docker-containere](https://phpsos.de/da/php2shell/docker-container-patchen/).

## Vælg den rigtige image-variant

| Variant | Indhold | Typisk anvendelse |
|---|---|---|
| `php:<version>-fpm` | PHP-FPM, kræver en foranstillet webserver | produktion med Nginx, Caddy eller en ingress |
| `php:<version>-apache` | Apache med mod_php, som standard mpm_prefork | enkle opbygninger, ældre applikationer |
| `php:<version>-cli` | kommandolinje, indeholder som eneste variant også php-cgi | cronjobs, kø-workers, build-trin |
| `…-alpine` | på Alpine Linux med musl | små images, ved nogle udvidelser er tilpasninger nødvendige |
| `…-bookworm`, `…-trixie` | på den nævnte Debian-version | fast basis til reproducerbare builds |

Til nye projekter anbefales som regel `fpm`-varianten med en separat webserver-container. Ved mod_php ser PHP-teamet i forbindelse med PHP2Shell den højeste risiko; den, der bruger `apache`-imaget, driver netop denne driftsform.

## Byg et produktions-image

Et slankt eksempel på en applikation med MySQL-adgang:

```dockerfile
FROM php:8.4-fpm-alpine

# Aktivér produktionskonfigurationen (ifølge image-dokumentationen kraftigt anbefalet)
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

# Kun nødvendige udvidelser
RUN docker-php-ext-install -j"$(nproc)" pdo_mysql

# Egne indstillinger
COPY zz-sicherheit.ini "$PHP_INI_DIR/conf.d/"

# Koden tilhører root; FPM-workers kører som www-data og kan kun læse den
COPY . /var/www/html
```

Image-hjælpescriptsene overtager bygningen af udvidelser: `docker-php-ext-configure` til indstillinger, `docker-php-ext-install` til bygning, `docker-php-ext-enable` til aktivering, f.eks. efter `pecl install`. Pakkes kildekoden ud med `docker-php-source`, bør den ifølge dokumentationen slettes igen i det samme lag. Filen `zz-sicherheit.ini` kunne se sådan ud:

```ini
expose_php = Off
display_errors = Off
log_errors = On
session.use_strict_mode = 1
session.cookie_httponly = 1
```

To yderligere grundsætninger gør images mere robuste. For det første indeholder det leverede image kun, hvad der er brug for under kørslen; compilere, pakke-caches og testfiler hører til i et eget build-trin. For det andet må den bruger, PHP kører under, kun skrive dér, hvor det er nødvendigt, f.eks. i upload- eller cachemapper på tilsluttede volumes. Mange teams driver desuden containeren med et skrivebeskyttet filsystem. En indsmuglet PHP-fil har det så betydeligt sværere ved at forblive varigt, og hver genstart genopretter imagets rene tilstand. Det erstatter ingen undersøgelse efter en hændelse, men formindsker angrebsfladen mærkbart.

## Processer, hukommelse og logs i containeren

Tre justeringsskruer afgør, om en PHP-container kører stabilt.

1. **Antal workers:** `pm.max_children` i FPM-poolen fastlægger, hvor mange forespørgsler der behandles samtidigt. Hver worker kan optage op til `memory_limit`.
2. **Containerens hukommelsesgrænse:** Den begrænser alle processer tilsammen. Som grov regel gælder: Antal workers gange hukommelse pr. worker plus reserve skal passe under grænsen, ellers afslutter systemet processer.
3. **Logs:** Containere skriver logs til standardoutput. I PHP-FPM videresender `catch_workers_output = yes` workernes output til hovedloggen; uden indstillingen havner det ifølge manualen i intet.

Hjælpsomt er desuden `request_terminate_timeout`, som afslutter enkelte forespørgsler efter et tidsrum, hvis `max_execution_time` ikke slår til. Hvordan I driver containere i klyngen, beskriver [Patch PHP i Kubernetes](https://phpsos.de/da/server/kubernetes/).

## Containere og sikkerhed: hvad PHP2Shell har vist

Ved PHP2Shell spiller containere en dobbelt rolle. På den ene side er de en hjælp: php.net anbefaler som midlertidig foranstaltning til CVE-2026-109618 at kombinere `memory_limit=-1` med en hukommelsesgrænse via container eller cgroup, ideelt sådan at kun den berørte worker afsluttes. `RLIMIT_AS` og `RLIMIT_DATA` er hertil ifølge php.net uegnede. Denne foranstaltning er ingen fuldstændig beskyttelse og erstatter ikke opdateringen.

På den anden side er containere en fælde, hvis images ikke bygges på ny. Et image med PHP 8.4.26 forbliver sårbart, uanset hvor ofte containeren genstarter. Først et nybyg til 8.4.27 eller nyere og udskiftningen af alle kørende containere lukker sårbarheden. Status kan kontrolleres direkte i den kørende container:

```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"));'
```

Leverer den sidste kommando `bool(false)`, kender PHP ikke det direktiv, der blev indført med rettelsesversionerne; ifølge manualen er versionen så berørt. Varigt hjælper kun et automatisk nybyg, som beskrevet under [CI/CD: byg PHP-images automatisk på ny](https://phpsos.de/da/blog/php-images-in-ci-neu-bauen/).

> **Tip:**
> Fastlæg i Dockerfile den nøjagtige PHP-version i tagget, og forøg den bevidst. Så kan det spores i koden, hvornår hvilken version blev udrullet.

## Hvordan hjælper PHP SOS konkret?

Ved [serverhærdningen for PHP-webservere](https://phpsos.de/da/leistungen/server-haertung/) tager vi os også af containere:

- **Kontrollere images:** Basis-image, PHP-version, udvidelser og konfiguration for hvert image.
- **Hærde konfigurationen:** Produktions-ini, slank udvidelsesliste, passende worker- og hukommelsesgrænser.
- **Opsætte nybyg:** Et forløb, der bygger images på ny og udruller dem ved nye PHP-udgivelser.
- **Kontrollere kørselsmiljøet:** Vi dokumenterer, at den rettede version kører i hver kørende container.


## Ofte stillede spørgsmål

**Hvilken variant af PHP-imaget er den rigtige?**  
Til Nginx eller en anden proxy fpm-varianten, til en enkel opbygning med Apache apache-varianten, til scripts og cronjobs cli-varianten. Alpine-varianter er mindre, men bygger på musl i stedet for glibc, hvilket kan mærkes ved nogle udvidelser.

**Opdateres PHP i containeren automatisk?**  
Nej. En kørende container ændrer sig ikke. I skal bygge imaget på ny med den nye PHP-version og genstarte containerne. Først derefter kører den rettede version.

**Hvordan forholder memory_limit og containergrænsen sig til hinanden?**  
memory_limit begrænser hver enkelt PHP-forespørgsel, containergrænsen hele containeren. Begge skal passe sammen: Antallet af workers gange hukommelse pr. worker bør ligge under containergrænsen.

**Har jeg brug for en php.ini i containere?**  
Ja. De officielle images leverer php.ini-development og php.ini-production med som skabeloner. Til produktion anbefaler image-dokumentationen udtrykkeligt produktionsskabelonen; egne indstillinger kommer i conf.d.

## Kilder

- [Docker Official Image: PHP](https://hub.docker.com/_/php)
- [PHP-manualen: FPM-konfiguration](https://www.php.net/manual/en/install.fpm.configuration.php)
- [php.net: Sikkerhedsmeddelelse af 21.10.2026](https://www.php.net/)
