Een PHP-applicatie containeriseren
Schrijf een productieklare PHP-Dockerfile.
Een PHP-applicatie containeriseren is een gratis PHP Academy-les op CoddyKit. Dit is les 1 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject PHP Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus PHP Academy bevat in totaal 4 lessen.
Waarom PHP in containers?
PHP reproduceerbaar uitleveren betekent dat je de exacte interpreterversie, extensies en OS-bibliotheken samen met je code vastlegt. Een Docker-image geeft elke omgeving — laptop, CI en productie — dezelfde php -v en dezelfde set ext-*.
In deze les bouwen we een productieklaar image: PHP-FPM, alleen de benodigde extensies, afgestemde configuratie, een gebruiker zonder rootrechten en een gezondheidscontrole.
FPM versus Apache als basis
De officiële PHP-images zijn in verschillende varianten beschikbaar. Kies voor een productiewebapplicatie achter nginx of traefik bij voorkeur php:8.3-fpm-alpine (klein) of php:8.3-fpm (Debian, glibc — minder verrassingen met systeembibliotheken).
cli— werkers, wachtrijen en cronfpm— FastCGI-procesbeheerder, te combineren met nginxapache— meegeleverde Apache, handig maar zwaarder
Leg de minorversie vast. Gebruik nooit :latest in productie.
# Base image choice in your Dockerfile
FROM php:8.3-fpm-alpine AS base
# Why alpine? ~30MB base vs ~140MB Debian.
# Tradeoff: musl libc, occasional native-extension friction.Extensies installeren
Gebruik nooit apt install php-xxx in deze images — gebruik de meegeleverde hulpmiddelen docker-php-ext-install, docker-php-ext-configure en pecl. Het script install-php-extensions (mlocati) is de feitelijke snelkoppeling die de juiste ontwikkelbestanden voor je ophaalt.
FROM php:8.3-fpm-alpine
# Grab the helper that resolves build deps automatically
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions \
pdo_mysql \
opcache \
intl \
zip \
redis \
bcmathComposer in de image
Kopieer het Composer-binaire bestand uit de officiële image in plaats van een installatieprogramma op te halen met curl. Voer voor productie composer install uit met --no-dev en --optimize-autoloader, en kopieer eerst alleen composer.json/composer.lock, zodat de afhankelijkheidslaag onafhankelijk van broncodewijzigingen kan worden gecachet.
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /app
# Cache-friendly: deps layer invalidates only when lock changes
COPY composer.json composer.lock ./
RUN composer install \
--no-dev \
--no-scripts \
--no-autoloader \
--prefer-dist
COPY . .
RUN composer dump-autoload --optimize --classmap-authoritativephp.ini afstemmen
De basisimage bevat de sjablonen php.ini-production en php.ini-development. Activeer de productievariant en plaats daarna je eigen overschrijvingen in conf.d — die map wordt als laatste samengevoegd en heeft dus voorrang.
Belangrijke productiewaarden: opcache.enable=1, opcache.validate_timestamps=0 (onwijzigbare code in de image) en een verstandige memory_limit.
# Activate production ini
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# Custom overrides win because conf.d loads last
COPY docker/php/zz-app.ini $PHP_INI_DIR/conf.d/zz-app.iniHet overschrijvingsbestand voor OPcache
Dit levert in productie de grootste winst op. Met validate_timestamps=0 controleert PHP bij elk verzoek niet langer de bestandsmetadata — maar dat betekent dat je de image MOET herbouwen om wijzigingen uit te rollen (precies wat we willen bij onveranderlijke containers).
; docker/php/zz-app.ini
memory_limit = 256M
expose_php = Off
opcache.enable = 1
opcache.enable_cli = 0
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.validate_timestamps = 0
opcache.preload = /app/preload.php
opcache.preload_user = www-dataUitvoeren zonder rootrechten
De image definieert www-data al. FPM als root uitvoeren vergroot het aanvalsoppervlak onnodig. Stel het eigenaarschap van schrijfbare paden (cache en logboeken) in en wissel vóór CMD van gebruiker met USER.
Luistert het hoofdproces van FPM dan nog naar bevoorrechte poorten? Nee — FPM luistert op 9000 (niet-bevoorrecht), dus uitvoeren zonder rootrechten is eenvoudig.
# Make runtime-writable dirs owned by the runtime user
RUN chown -R www-data:www-data /app/var /app/storage 2>/dev/null || true
USER www-data
EXPOSE 9000
CMD ["php-fpm"]Gezondheidscontroles
Orchestrators hebben een signaal nodig dat FPM echt actief is, niet alleen dat het proces bestaat. cgi-fcgi kan de FPM-/status- of /ping-eindpunt ondervragen. Schakel eerst pm.status_path en ping.path in de FPM-pool in.
# In www.conf pool config:
; ping.path = /ping
; ping.response = pong
# Dockerfile HEALTHCHECK using cgi-fcgi
RUN install-php-extensions @composer >/dev/null 2>&1 || true
HEALTHCHECK --interval=10s --timeout=3s --retries=3 \
CMD SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping REQUEST_METHOD=GET \
cgi-fcgi -bind -connect 127.0.0.1:9000 || exit 1Het Dockerfile samenstellen
Hier staat een coherent Dockerfile voor productie met één fase. In de volgende les splitsen we het op in meerdere fasen om bouwtools weg te laten. Let op de volgorde: afhankelijkheden → configuratie → broncode → automatisch laden → overschakelen naar de gebruiker.
FROM php:8.3-fpm-alpine
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions pdo_mysql opcache intl zip redis
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /app
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
COPY docker/php/zz-app.ini $PHP_INI_DIR/conf.d/
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist
COPY . .
RUN composer dump-autoload --optimize --classmap-authoritative && \
chown -R www-data:www-data /app/var
USER www-data
EXPOSE 9000
CMD ["php-fpm"]De build controleren
Controleer na het bouwen wat er daadwerkelijk in de image terecht is gekomen: de PHP-versie, geladen extensies en of de validatie van OPcache uitstaat. Een snel CLI-script bevestigt het runtimecontract waarop je app vertrouwt.
<?php
// Run inside the container: php verify.php
echo 'PHP ' . PHP_VERSION . PHP_EOL;
$required = ['pdo_mysql', 'opcache', 'intl', 'zip'];
foreach ($required as $ext) {
printf("%-12s %s\n", $ext, extension_loaded($ext) ? 'OK' : 'MISSING');
}
var_dump((bool) ini_get('opcache.enable'));
?>Hygiëne van de buildcontext
Een .dockerignore houdt je buildcontext klein en voorkomt dat geheimen en opgeblazen vendor-mappen in de image lekken en de cache ongeldig maken. Sluit vendor, versiebeheer, omgevingsbestanden en lokale hulpmiddelen uit.
# .dockerignore
.git
.gitignore
vendor/
node_modules/
.env
.env.*
tests/
*.md
docker-compose*.yml
storage/logs/*
var/cache/*Snelle controle
Waarom stel je opcache.validate_timestamps=0 in een productie-image in?
Samenvatting
Je hebt een PHP-FPM-image voor productie gebouwd: een vastgezette basis 8.3-fpm-alpine, alleen de benodigde extensies geïnstalleerd via het installatiescript, Composer gekopieerd en gecachte afhankelijkheden in een eigen laag geplaatst, de productie-php.ini met een OPcache-overschrijving geactiveerd, overgeschakeld naar www-data en een FPM-gezondheidscontrole toegevoegd.
Belangrijke gewoonten: zet versies vast, cache de laag met afhankelijkheden, voer uit als niet-rootgebruiker, schakel tijdstempelvalidatie uit en houd de buildcontext slank met .dockerignore.
Leer PHP met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 49
- Lessen
- 195
Veelgestelde vragen
Is de les “Een PHP-applicatie containeriseren” gratis?
Ja — de volledige tekst van “Een PHP-applicatie containeriseren” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus PHP Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus PHP Academy bevat in totaal 4 lessen.
Wat leer ik in “Een PHP-applicatie containeriseren”?
Schrijf een productieklare PHP-Dockerfile. Je oefent met PHP Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met PHP Academy te beginnen?
Ervaring vooraf is niet nodig. PHP Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.
Hoe lang duurt de les “Een PHP-applicatie containeriseren”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over PHP Academy?
Ja. Elke les over PHP Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Een PHP-applicatie containeriseren
- Builds met meerdere fasen en optimalisatie
- Docker Compose voor lokale stacks
- CI/CD met GitHub Actions