PHP Academy · Lektion

Containerisera en PHP-applikation

Skriv en produktionsklar PHP Dockerfile.

Lektion 1 av 413 steg

Containerisera en PHP-applikation är en gratis lektion i PHP Academy på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för PHP Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i PHP Academy innehåller totalt 4 lektioner.

Varför containerisera PHP

Att leverera PHP reproducerbart innebär att låsa fast den exakta versionen av tolken, tilläggen och operativsystemets bibliotek tillsammans med koden. En Docker-avbildning ger varje miljö – den bärbara datorn, CI och produktionen – samma php -v och samma uppsättning ext-*.

I den här lektionen bygger vi en produktionsklar avbildning: PHP-FPM, endast de tillägg Ni behöver, finjusterade konfigurationer, en icke-root-användare och en hälsokontroll.

FPM kontra Apache som bas

De officiella PHP-avbildningarna finns i flera varianter. För en produktionsapplikation bakom nginx eller traefik bör Ni föredra php:8.3-fpm-alpine (liten) eller php:8.3-fpm (Debian, glibc – färre överraskningar med inbyggda bibliotek).

  • cli – arbetare, köer och cron
  • fpm – FastCGI-processhanterare, används tillsammans med nginx
  • apache – medföljande Apache, bekvämt men tyngre

Lås fast minorversionen. Använd aldrig :latest i produktion.

# 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.

Installera tillägg

Kör aldrig apt install php-xxx i dessa avbildningar – använd de medföljande hjälpprogrammen docker-php-ext-install, docker-php-ext-configure och pecl. Skriptet install-php-extensions (mlocati) är den inofficiella standardgenvägen som hämtar rätt utvecklingsheaders åt Er.

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 \
        bcmath

Composer i avbildningen

Kopiera Composer-binären från dess officiella avbildning i stället för att hämta ett installationsprogram med curl. Kör composer install med --no-dev och --optimize-autoloader i produktion, och kopiera först endast composer.json/composer.lock så att beroendelagret kan cachas oberoende av ändringar i källkoden.

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-authoritative

Finjustera php.ini

Basavbildningen levereras med mallarna php.ini-production och php.ini-development. Aktivera produktionsmallen och lägg sedan Era egna åsidosättningar i conf.d – den katalogen slås samman sist, så dess värden gäller.

Viktiga produktionsvärden är opcache.enable=1, opcache.validate_timestamps=0 (oföränderlig kod i avbildningen) och en rimlig 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.ini

Åsidosättningsfilen för OPcache

Det här är den största enskilda produktionsvinsten. Med validate_timestamps=0 kontrollerar PHP aldrig filerna vid varje förfrågan – men det innebär att Ni MÅSTE bygga om avbildningen för att distribuera ändringar (vilket är precis vad vi vill uppnå med oföränderliga 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-data

Kör som icke-root

Avbildningen definierar redan www-data. Att köra FPM som root ökar attackytan i onödan. Ange ägarskap för skrivbara sökvägar (cache och loggar) och byt användare med USER före CMD.

Binder FPM:s huvudprocess fortfarande till privilegierade portar? Nej – FPM lyssnar på port 9000 (utan särskilda privilegier), så det är enkelt att köra som icke-root.

# 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"]

Hälsokontroller

Orkestreringsverktyg behöver en signal som visar att FPM faktiskt lever, inte bara att processen existerar. cgi-fcgi kan pinga FPM:s /status- eller /ping-endpoint. Aktivera först pm.status_path och ping.path i FPM-poolen.

# 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 1

Sätta ihop Dockerfile

Här är en sammanhängande Dockerfile för produktion i ett enda steg. I nästa lektion delar vi upp den i flera steg för att ta bort byggverktyg. Lägg märke till ordningen: beroenden → konfiguration → källkod → autoload → byt användare.

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"]

Verifiera bygget

Efter bygget gör ni en snabb rimlighetskontroll av vad som faktiskt hamnade i imagen: PHP-versionen, laddade tillägg och att OPcache-validering är avstängd. Ett kort CLI-skript bekräftar det runtime-kontrakt som appen är beroende av.

<?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'));
?>

Ren byggkontext

En .dockerignore håller byggkontexten liten och förhindrar att hemligheter och överflödiga vendor-filer läcker in i imagen och slår sönder cachen. Exkludera vendor, VCS, env-filer och lokala verktyg.

# .dockerignore
.git
.gitignore
vendor/
node_modules/
.env
.env.*
tests/
*.md
docker-compose*.yml
storage/logs/*
var/cache/*

Snabbkontroll

Varför ska opcache.validate_timestamps=0 ställas in i en produktionsimage?

Sammanfattning

Ni byggde en PHP-FPM-image för produktion: en bas av typen 8.3-fpm-alpine med låst version, installerade enbart nödvändiga tillägg via installationsskriptet, kopierade Composer och cachade beroenden i ett eget lager, aktiverade produktions-php.ini med en OPcache-override, bytte till www-data och lade till en FPM-healthcheck.

Viktiga vanor: lås versioner, cacha beroendelagret, kör som icke-root, inaktivera tidsstämpelvalidering och håll byggkontexten liten med .dockerignore.

Gratis att börja

Lär dig PHP med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
49
Lektioner
195

Vanliga frågor

Är lektionen ”Containerisera en PHP-applikation” gratis?

Ja – hela texten till ”Containerisera en PHP-applikation” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i PHP Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i PHP Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Containerisera en PHP-applikation”?

Skriv en produktionsklar PHP Dockerfile. Ni övar på PHP Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig PHP Academy?

Du behöver inga förkunskaper. Utbildningen i PHP Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.

Hur lång tid tar lektionen ”Containerisera en PHP-applikation”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här PHP Academy-lektionen?

Ja. Varje PHP Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Containerisera en PHP-applikation
  2. Byggen i flera steg och optimering
  3. Docker Compose för lokala stackar
  4. CI/CD med GitHub Actions
← Tillbaka till PHP Academy