Builds i flere trin og optimering
Gør images mindre, og adskil build fra runtime.
Builds i flere trin og optimering er en gratis PHP Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i PHP Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. PHP Academy-kurset indeholder 4 lektioner i alt.
Hvorfor flere trin
Et image i ét trin tager Composer, buildafhængigheder, udviklingsheaders og din tests/-mappe med ind i produktionen. Builds i flere trin lader dig kompilere og installere i et omfattende byggetrin og kun kopiere de færdige artefakter til et slankt kørselstrin.
Resultatet er mindre images, en mindre angrebsflade, hurtigere hentninger og ingen compilere i produktionen.
Navngivne trin
Hver FROM ... AS name starter et nyt trin. Senere trin kan COPY --from=name filer ud fra tidligere trin. Kun det sidste trin bliver til dit image; mellemliggende trin kasseres, men caches.
# Stage 1: dependencies
FROM composer:2 AS vendor
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --prefer-dist --ignore-platform-reqs
# Stage 2: runtime
FROM php:8.3-fpm-alpine AS runtime
WORKDIR /app
COPY --from=vendor /app/vendor ./vendor
COPY . .Adskillelse af buildafhængigheder
Kompilering af udvidelser kræver autoconf, gcc og udviklingsheaders — ingen af delene hører hjemme i kørselsmiljøet. Brug installationsprogrammet i et byggetrin, og kopiér derefter de kompilerede .so-filer og den tilsvarende conf.d-konfiguration til et rent kørselstrin.
FROM php:8.3-fpm-alpine AS ext-builder
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 redis igbinary opcache intl
FROM php:8.3-fpm-alpine AS runtime
# Copy compiled extensions + their enable configs
COPY --from=ext-builder /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/
COPY --from=ext-builder /usr/local/etc/php/conf.d/ /usr/local/etc/php/conf.d/Rækkefølge for lagcaching
Docker cacher lag fra top til bund og ugyldiggør alt under et ændret lag. Arrangér dem fra mindst til hyppigst ændrede:
- Basisimage + udvidelser (sjældent)
composer.lock+ installation (lejlighedsvis)- Programmets kildekode (ved hver commit)
- Autoload-dump (ved hver commit)
Det betyder, at en ændring, der kun berører koden, genbruger hele det cachede vendor-lag.
# BAD: copying all source before composer install
# busts the vendor layer on every code change
COPY . .
RUN composer install
# GOOD: lock first, then source
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-autoloader
COPY . .
RUN composer dump-autoload --optimizeCachemonteringer i BuildKit
Med BuildKit (DOCKER_BUILDKIT=1) kan du montere en vedvarende cache, som overlever mellem builds uden at ende i imaget. Det er perfekt til Composers globale cache, så gentagne builds ikke behøver hente pakker igen.
# syntax=docker/dockerfile:1
FROM composer:2 AS vendor
WORKDIR /app
COPY composer.json composer.lock ./
RUN --mount=type=cache,target=/tmp/composer-cache \
COMPOSER_CACHE_DIR=/tmp/composer-cache \
composer install --no-dev --prefer-distMåling af imagestørrelse
Undersøg lagfordelingen for at finde overflødigt indhold. docker history viser, hvor meget hver instruktion tilføjede; værktøjer som dive viser spildplads. Målet er et kørselstrin uden compilere, Composer eller udviklingsafhængigheder.
# Compare sizes
docker images myapp
# Per-layer contribution
docker history --no-trunc --format '{{.Size}}\t{{.CreatedBy}}' myapp:latest
# Deep inspection of wasted bytes
dive myapp:latestTrimning af det sidste trin
Kørselstrinnet bør IKKE indeholde Composer, scriptet til installation af udvidelser eller din testpakke. Kopiér vendor og kildekoden fra byggetrinene; kør aldrig composer i det sidste trin. Fjern installationsprogrammet efter brug, hvis du er nødt til at køre det dér.
FROM php:8.3-fpm-alpine AS runtime
WORKDIR /app
# bring extensions + vendor in from builders — no Composer here
COPY --from=ext-builder /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/
COPY --from=ext-builder /usr/local/etc/php/conf.d/ /usr/local/etc/php/conf.d/
COPY --from=vendor /app/vendor ./vendor
COPY . .
USER www-data
CMD ["php-fpm"]Begrænsninger ved distroless / scratch
PHP kan ikke køre på et helt tomt scratch-image — det kræver libc og delte biblioteker. Den mindste praktiske løsning er alpine (musl) eller et minimalt Debian-image i distroless-stil. Alpine er mindst, men vær opmærksom på native biblioteker, der forventer glibc; hvis du får segmenteringsfejl med NSS/ICU, så fald tilbage til php:8.3-fpm-bookworm.
# Smallest practical PHP runtime
FROM php:8.3-fpm-alpine
# If musl causes native-lib issues (e.g., some ICU edge cases),
# the glibc Debian slim variant is the safe fallback:
# FROM php:8.3-fpm-bookwormMålretning mod trin
Én Dockerfil kan bruges til både udvikling og produktion via --target. Tilføj et dev-trin oven på runtime, som tilføjer Composers udviklingsafhængigheder og Xdebug igen; byg --target=runtime til produktion og --target=dev lokalt.
FROM runtime AS dev
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 xdebug @composer
USER root
RUN composer install # includes dev deps
# Build prod: docker build --target runtime -t app:prod .
# Build dev: docker build --target dev -t app:dev .Sådan tænker du over lagstørrelser
En enkel mental model hjælper dig med at forudsige cacheadfærden. Dette CLI-udsnit simulerer den klassiske fejl med ubegrænset lagvækst kontra et lag med loft og viser, hvorfor det er vigtigt at samle oprydningen i den samme RUN.
<?php
// Simulate layer sizes (MB) for two strategies
$installSteps = [120, 8, 8, 8];
// Separate RUN per step keeps temp files in layers
$separate = array_sum($installSteps);
// Single RUN with cleanup removes temp files before commit
$combined = max($installSteps); // peak, then cleaned
echo "Separate layers total: {$separate} MB\n";
echo "Combined+cleanup: {$combined} MB\n";
echo 'Saved: ' . ($separate - $combined) . " MB\n";
?>Kombinér og ryd op i én RUN
Hver RUN er et lag; sletning af filer i et senere lag gør ikke imaget mindre, fordi de tidligere lag stadig indeholder bytesene. Installér, brug og ryd op i den samme RUN, så de midlertidige filer aldrig bliver gemt i imaget.
RUN apk add --no-cache --virtual .build-deps $PHPIZE_DEPS && \
pecl install redis && \
docker-php-ext-enable redis && \
apk del .build-deps && \
rm -rf /tmp/pear /var/cache/apk/*Hurtigt tjek
Hvorfor skal buildafhængigheder fjernes i den samme RUN, som installerede dem?
Opsummering
Builds i flere trin holder compilere og udviklingsafhængigheder ude af produktionen. Du har lært at navngive trin og bruge COPY --from til artefakter, arrangere lag fra mindst til mest flygtige for at optimere caching, bruge BuildKit-cachemonteringer til Composer, måle størrelsen med docker history/dive, vælge mellem alpine og glibc bevidst, målrette udviklings- og produktionstrin samt samle installation og oprydning i én RUN.
Lær PHP med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 49
- Lektioner
- 195
Ofte stillede spørgsmål
Er lektionen “Builds i flere trin og optimering” gratis?
Ja — hele teksten til “Builds i flere trin og optimering” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af PHP Academy-kurset, skal du opgradere til CoddyKit PRO. PHP Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Builds i flere trin og optimering”?
Gør images mindre, og adskil build fra runtime. Du øver dig i PHP Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på PHP Academy?
Der kræves ingen tidligere erfaring. PHP Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “Builds i flere trin og optimering”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne PHP Academy-lektion?
Ja. Alle PHP Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Containerisering af en PHP-applikation
- Builds i flere trin og optimering
- Docker Compose til lokale stacks
- CI/CD med GitHub Actions