# PHP:n paikallinen kehitys: Docker, DDEV ja muut

> PHP:n paikallinen kehitys sisäänrakennetulla palvelimella, Dockerilla tai DDEV:llä: vahvuudet, rajat, esimerkit ja kehityksen ja tuotannon yhdenmukaisuus.

Lähde: https://phpsos.de/fi/php/php-lokal-entwickeln/  
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 paikalliseen kehitykseen on kolme yleistä tapaa: sisäänrakennettu verkkopalvelin (`php -S`) nopeisiin kokeiluihin, viralliset PHP-Docker-kuvat jäljennettäviin ympäristöihin sekä työkalut kuten DDEV, jotka luovat valmiita projektiympäristöjä WordPressille, TYPO3:lle, Shopwarelle tai Laravelille. Ratkaisevaa on vähemmän työkalu kuin vastaavuus: paikallisesti pitäisi ajaa samaa PHP-versiota samoilla laajennuksilla kuin tuotannossa. Tietoturvan kannalta ratkaisee kuitenkin aina palvelimen ajoympäristö.

## Miksi oma kehitysympäristö?

Muutosten tekeminen suoraan tuotantopalvelimella on riskialtista: jokainen kirjoitusvirhe näkyy heti asiakkaille, ja testitiedostot jäävät mielellään paikalleen. Paikallinen ympäristö erottaa kokeilun käytöstä. Se on samalla paikka, jossa uudet PHP-versiot ja tietoturvapäivitykset testataan ensin.

Johdolle ja IT-päällikölle kysymys ei siis ole siitä, onko kehitysympäristöä, vaan siitä, vastaako se tuotantojärjestelmää. Paikallinen ympäristö PHP 8.4:llä, kun tuotannossa on vielä 8.1, peittää ongelmia sen sijaan, että näyttäisi ne. Sama pätee tietokantaversioon, verkkopalvelimeen ja laajennuksiin kuten `intl`, `gd` tai `pdo_mysql`: yksikin puuttuva laajennus voi johtaa siihen, että virhe huomataan vasta tuotannossa.

## Vaihtoehdot pähkinänkuoressa

| Vaihtoehto | Sopii | Vahvuudet | Rajat |
|---|---|---|---|
| Sisäänrakennettu palvelin `php -S` | lyhyisiin kokeiluihin, pieniin komentosarjoihin | ei vaadi muun ohjelmiston asennusta | ei korvaa Nginxiä tai Apachea, ei julkisiin verkkoihin |
| Virallinen Docker-kuva | tiimeille, jäljennettäviin ympäristöihin | versio lukittavissa tunnisteella, lähellä konttikäyttöä | konfiguraatio ja usean kontin yhteispeli rakennettava itse |
| DDEV | CMS- ja kehyshankkeisiin | valmiit projektityypit, tietokanta ja verkkopalvelin mukana | edellyttää Dockeria, omat käytäntönsä |
| Paikallisesti asennettu PHP | yksittäisille kehittäjille | nopea, suora | usean hankkeen versioita vaikea pitää rinnakkain |

## Sisäänrakennettu verkkopalvelin

Versiosta PHP 5.4 lähtien komentorivi sisältää pienen verkkopalvelimen. Se käynnistyy nykyisessä hakemistossa tai valitsimella `-t` toisessa dokumenttihakemistossa:

```bash
php -S localhost:8000 -t public/
```

Valinnaisesti annetaan reititinkomentosarja, joka suoritetaan ensin jokaisella pyynnöllä. Käsikirja on luokittelussa yksiselitteinen: palvelimen on tarkoitus tukea kehitystä, se ei ole täysimittainen verkkopalvelin eikä sitä pidä käyttää julkisessa verkossa. Sitokaa se siksi osoitteeseen `localhost`, ei osoitteeseen `0.0.0.0`, muuten se voi olla tavoitettavissa yrityksen tai hotellin WLAN-verkossa. Lisää komentorivistä sivulla [PHP komentorivillä](https://phpsos.de/fi/php/php-cli/).

## Docker: viralliset PHP-kuvat

Viralliset kuvat tulevat useina varianteina: `cli` komentoriville, `apache` Apachella ja mod_php:llä, `fpm` käyttöön Nginxin tai muun välityspalvelimen takana sekä Alpine-variantit pieniin kuviin. Nopea aloitus Apachella:

```bash
docker run --rm -p 8080:80 -v "$PWD":/var/www/html php:8.4-apache
```

Kuvat sisältävät pohjat `php.ini-development` ja `php.ini-production` hakemistossa `$PHP_INI_DIR`. Paikallisesti kehityspohja on järkevä, koska se näyttää virheet. Tuotantoon kuvan dokumentaatio suosittelee nimenomaisesti tuotantopohjaa. Laajennukset asennetaan mukana tulevilla apukomentosarjoilla `docker-php-ext-configure`, `docker-php-ext-install` ja `docker-php-ext-enable`. Miten tunnisteet ja digestit toimivat, selittää [Viralliset PHP-Docker-kuvat](https://phpsos.de/fi/blog/offizielle-php-docker-images/).

## DDEV: valmiit ympäristöt CMS:lle ja kehyksille

DDEV rakentuu Dockerin päälle ja pystyttää hankkeelle verkkopalvelimen, PHP:n, tietokannan ja aputoiminnot. Pikaoppaat seuraavat lähes aina samaa kaavaa:

```bash
ddev config --project-type=wordpress --docroot=web
ddev start
ddev composer install
ddev launch
```

Projektityyppeinä DDEV tuntee muun muassa `wordpress`, `typo3`, `shopware6`, `laravel`, `symfony`, `drupal11`, `magento2` ja yleisen tyypin `php`. PHP-version määritätte tiedostossa `.ddev/config.yaml`; dokumentaation mukaan mahdollisia ovat versiot 5.6:sta 8.5:een, oletus on 8.4:

```yaml
# .ddev/config.yaml (ote)
php_version: "8.3"
webserver_type: nginx-fpm   # vaihtoehtoisesti apache-fpm
```

Näin paikallinen ympäristö vastaa tuotantoversiota, vaikka se ei olisikaan uusin.

## Paikallinen kehitys, korjaustaso ja PHP2Shell

PHP2Shellin jälkeen useat alustatoimittajat ovat huomauttaneet tyypillisestä ajatusvirheestä. Vercel korostaa tiedotteessaan, ettei paikallisen kehitysympäristön, sovelluskoodin tai lisäosien päivitys riitä; ratkaisevaa on PHP-ajoympäristö, joka todella tuottaa sisällön. Paikallinen PHP 8.4.27 ei suojaa palvelinta, jolla on 8.4.26.

Toisaalta kehitysympäristö tuo omia riskejään, jotka voivat siirtyä tuotantoon:

1. **Kehitys-ini tuotannossa:** `display_errors` on päällä tiedostossa `php.ini-development`. Jos tämä tiedosto päätyy palvelimelle, kävijät näkevät polkuja ja virheilmoituksia. Katso [Virheiden näytön poistaminen tuotannosta](https://phpsos.de/fi/blog/display-errors-produktion/).
2. **Unohdetut testitiedostot:** `phpinfo()`-tiedostot, tietokantavedokset tai `.env`-tiedostot tunnuksineen eivät kuulu käyttöönottoon.
3. **Avoimet kehityspalvelimet:** `php -S` tai kontit, joiden portit on julkaistu verkossa olevilla koneilla.
4. **Vanhentuneet kuvat:** Paikalliset kuvat eivät päivity itsestään; PHP:n tietoturvajulkaisun jälkeen myös kehitysympäristö kuuluu rakentaa uudelleen, jotta testit ajetaan korjatulla versiolla.

> **Vinkki:**
> Määrittäkää PHP-versio yhdessä paikassa, esimerkiksi Dockerfilessä tai tiedostossa `.ddev/config.yaml`, ja muuttakaa se päivityksissä yhdessä palvelinkonfiguraation kanssa.

## Miten PHP SOS auttaa konkreettisesti?

[Tietoturvahuoltosopimuksessa](https://phpsos.de/fi/leistungen/security-wartungsvertrag/) huolehdimme siitä, että kehitys ja käyttö sopivat yhteen:

- **Vertailu:** Vertaamme kehitys-, testi- ja tuotantoympäristön PHP-versiota ja laajennuksia.
- **Päivitysten kulku:** Uudet PHP-julkaisut asennetaan ensin testiympäristöön, sitten tuotantoon, kumpaankin uudelleenkäynnistyksellä.
- **Käyttöönoton tarkistus:** Huolehdimme siitä, ettei kehitys-inita, testitiedostoja tai tunnuksia päädy palvelimelle.
- **Dokumentointi:** Tiedätte milloin tahansa, mikä versio on käytössä missäkin.


## Usein kysytyt kysymykset

**Saanko käyttää PHP:n sisäänrakennettua verkkopalvelinta julkisesti?**  
Et saa. PHP-käsikirja sanoo nimenomaisesti, että komennolla php -S käynnistetty palvelin on tarkoitettu kehitykseen eikä sitä pidä käyttää julkisessa verkossa. Tuotantoon kuuluu PHP-FPM Nginxin tai Apachen kanssa.

**Mikä DDEV on?**  
DDEV on Dockerin päälle rakentuva työkalu, joka luo valmiita kehitysympäristöjä PHP-hankkeille. Se tuntee projektityypit WordPressille, TYPO3:lle, Shopware 6:lle, Laravelille, Drupalille ja muille järjestelmille.

**Riittääkö, että päivitän paikallisen PHP-version?**  
Ei riitä. PHP2Shellin kaltaisia aukkoja vastaan ratkaisee PHP-ajoympäristö, joka todella tuottaa sisällön, eli palvelimella oleva. Paikallisella ympäristöllä pitäisi kuitenkin olla sama versio, jotta testit ovat luotettavia.

**Mitä php.ini-tiedostoa käytän paikallisesti?**  
Paikallisesti php.ini-development on järkevä, koska se näyttää virheet. Tuotannossa käytetään php.ini-production-tiedostoa. Viralliset Docker-kuvat sisältävät molemmat pohjat.

## Lähteet

- [PHP-käsikirja: sisäänrakennettu verkkopalvelin](https://www.php.net/manual/en/features.commandline.webserver.php)
- [Docker Official Image: PHP](https://hub.docker.com/_/php)
- [DDEV](https://ddev.com/)
