# Udvikl PHP lokalt: Docker, DDEV og co.

> Udvikl PHP lokalt med indbygget server, Docker eller DDEV: styrker, grænser, eksempler og hvordan udvikling og produktion holder samme patch-status.

Kilde: https://phpsos.de/da/php/php-lokal-entwickeln/  
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 udvikle PHP lokalt er der tre gængse veje: den indbyggede webserver (`php -S`) til hurtige forsøg, de officielle PHP-Docker-images til reproducerbare miljøer og værktøjer som DDEV, der frembringer færdige projektmiljøer til WordPress, TYPO3, Shopware eller Laravel. Afgørende er mindre værktøjet end overensstemmelsen: Lokalt bør samme PHP-version med samme udvidelser køre som live. For sikkerheden tæller til sidst dog altid runtime på serveren.

## Hvorfor et eget udviklingsmiljø?

At lave ændringer direkte på live-serveren er risikabelt: Hver tastefejl er straks synlig for kunderne, og testfiler bliver gerne liggende. Et lokalt miljø adskiller afprøvning fra drift. Det er samtidig stedet, hvor nye PHP-versioner og sikkerhedsopdateringer testes først.

For ledelsen og it-chefen er spørgsmålet derfor ikke, om der findes et udviklingsmiljø, men om det svarer til live-systemet. Et lokalt miljø med PHP 8.4, mens live stadig kører 8.1, tilslører problemer i stedet for at vise dem. Det samme gælder databaseversion, webserver og udvidelser som `intl`, `gd` eller `pdo_mysql`: Allerede en manglende udvidelse kan medføre, at en fejl først opdages live.

## Mulighederne i overblik

| Mulighed | Egnet til | Styrker | Grænser |
|---|---|---|---|
| Indbygget server `php -S` | korte forsøg, små scripts | uden installation af yderligere software | ingen erstatning for Nginx eller Apache, ikke til offentlige netværk |
| Officielt Docker-image | teams, reproducerbare miljøer | version kan fastlægges via tag, tæt på containerdrift | konfiguration og samspil mellem flere containere skal bygges selv |
| DDEV | CMS- og framework-projekter | færdige projekttyper, database og webserver inklusive | forudsætter Docker, egne konventioner |
| Lokalt installeret PHP | enkeltudviklere | hurtigt, direkte | versioner til flere projekter er svære at holde parallelt |

## Den indbyggede webserver

Siden PHP 5.4 indeholder kommandolinjen en lille webserver. Den starter i den aktuelle mappe eller med `-t` i en anden dokumentmappe:

```bash
php -S localhost:8000 -t public/
```

Valgfrit giver I et router-script, som kører først ved hver forespørgsel. Manualen er i sin vurdering entydig: Serveren skal støtte udviklingen, er ikke en fuldgyldig webserver og skal ikke bruges i et offentligt netværk. Bind den derfor til `localhost`, ikke til `0.0.0.0`, ellers kan den under omstændigheder nås i firmaets eller hotellets wifi. Mere om kommandolinjen under [PHP på kommandolinjen](https://phpsos.de/da/php/php-cli/).

## Docker: officielle PHP-images

De officielle images findes i flere varianter: `cli` til kommandolinjen, `apache` med Apache og mod_php, `fpm` til drift bag Nginx eller en anden proxy, dertil Alpine-varianter til små images. En hurtig start med Apache:

```bash
docker run --rm -p 8080:80 -v "$PWD":/var/www/html php:8.4-apache
```

Images indeholder skabelonerne `php.ini-development` og `php.ini-production` i mappen `$PHP_INI_DIR`. Lokalt er udviklingsskabelonen fornuftig, fordi den viser fejl. Til produktion anbefaler image-dokumentationen udtrykkeligt produktionsskabelonen. Udvidelser installerer I med de medfølgende hjælpescripts `docker-php-ext-configure`, `docker-php-ext-install` og `docker-php-ext-enable`. Hvordan tags og digests fungerer, forklarer [Officielle PHP-Docker-images](https://phpsos.de/da/blog/offizielle-php-docker-images/).

## DDEV: færdige miljøer til CMS og frameworks

DDEV bygger på Docker og opsætter til et projekt webserver, PHP, database og hjælpetjenester. Hurtigstartvejledningerne følger næsten altid det samme mønster:

```bash
ddev config --project-type=wordpress --docroot=web
ddev start
ddev composer install
ddev launch
```

Som projekttyper kender DDEV blandt andet `wordpress`, `typo3`, `shopware6`, `laravel`, `symfony`, `drupal11`, `magento2` og den generelle type `php`. PHP-versionen fastlægger I i `.ddev/config.yaml`; ifølge dokumentationen er versioner fra 5.6 til 8.5 mulige, standarden er 8.4:

```yaml
# .ddev/config.yaml (uddrag)
php_version: "8.3"
webserver_type: nginx-fpm   # alternativt apache-fpm
```

Sådan svarer det lokale miljø til live-versionen, også selv om denne endnu ikke er den nyeste.

## Lokal udvikling, patch-status og PHP2Shell

Efter PHP2Shell har flere platformudbydere peget på en typisk tankefejl. Vercel understreger ifølge bulletinen, at en opdatering af det lokale udviklingsmiljø, applikationskoden eller pluginsene ikke er nok; afgørende er den PHP-runtime, der faktisk leverer. At have PHP 8.4.27 lokalt beskytter ikke serveren med 8.4.26.

Omvendt bringer udviklingsmiljøet egne risici med, som kan vandre ind i produktionen:

1. **Udviklings-ini i produktion:** `display_errors` er slået til i `php.ini-development`. Havner denne fil på serveren, ser besøgende stier og fejlmeddelelser. Se [Slå fejlvisning fra i produktion](https://phpsos.de/da/blog/display-errors-produktion/).
2. **Glemte testfiler:** `phpinfo()`-filer, database-dumps eller `.env`-filer med adgangsdata hører ikke til i udrulningen.
3. **Åbne udviklingsservere:** `php -S` eller containere med udgivne porte på maskiner i netværket.
4. **Forældede images:** Lokale images opdateres ikke af sig selv; efter en PHP-sikkerhedsudgivelse bør også udviklingsmiljøet bygges om, så tests kører med den rettede version.

> **Tip:**
> Fastlæg PHP-versionen ét sted, f.eks. i Dockerfile eller i `.ddev/config.yaml`, og ændr den ved opdateringer sammen med serverkonfigurationen.

## Hvordan hjælper PHP SOS konkret?

I [sikkerhedsvedligeholdelsesaftalen](https://phpsos.de/da/leistungen/security-wartungsvertrag/) sørger vi for, at udvikling og drift passer sammen:

- **Afstemning:** Vi sammenligner PHP-version og udvidelser i udviklings-, test- og live-miljø.
- **Opdateringsforløb:** Nye PHP-udgivelser indspilles først i testmiljøet, derefter live, hver gang med genstart.
- **Kontrollere udrulningen:** Vi sørger for, at ingen udviklings-ini, testfiler eller adgangsdata havner på serveren.
- **Dokumentation:** I ved til enhver tid, hvilken version der kører hvor.


## Ofte stillede spørgsmål

**Må jeg bruge den indbyggede PHP-webserver offentligt?**  
Nej. PHP-manualen siger udtrykkeligt, at serveren startet med php -S tjener udvikling og ikke skal bruges i et offentligt netværk. Til drift hører PHP-FPM med Nginx eller Apache.

**Hvad er DDEV?**  
DDEV er et værktøj, der bygger på Docker og frembringer færdige udviklingsmiljøer til PHP-projekter. Det kender projekttyper til WordPress, TYPO3, Shopware 6, Laravel, Drupal og flere systemer.

**Er det nok at opdatere den lokale PHP-version?**  
Nej. Mod sårbarheder som PHP2Shell tæller den PHP-runtime, der faktisk leverer, altså den på serveren. Det lokale miljø bør dog have samme version, så tests er meningsfulde.

**Hvilken php.ini bruger jeg lokalt?**  
Lokalt er php.ini-development fornuftig, fordi den viser fejl. I produktion bør php.ini-production bruges. De officielle Docker-images har begge skabeloner med.

## Kilder

- [PHP-manualen: Indbygget webserver](https://www.php.net/manual/en/features.commandline.webserver.php)
- [Docker Official Image: PHP](https://hub.docker.com/_/php)
- [DDEV](https://ddev.com/)
