PHP uygulamaları için Docker imajlarının 1 GB'ı aşması alışılmış bir durum. Bunun başlıca nedenleri build araçları, geliştirme paketleri ve hiç temizlenmeyen katman önbellek şişmesidir. Multi-stage build'ler bu sorunu temiz bir şekilde çözer: tek bir aşamada build alır, yalnızca runtime artefaktları son ve yalın imaja kopyalarsınız.
Sorun
Tipik tek aşamalı bir PHP Dockerfile; Composer, Node, npm, build-essential ve çeşitli geliştirme başlıklarını çeker. Bunların hiçbiri runtime'da gerekli olmasa da tamamı nihai imajda yer alır. Başlangıç noktamız orta ölçekli bir Laravel uygulaması için 1.2 GB'lık bir imajdı.
Multi-Stage Yaklaşımı
Püf nokta, build bağımlılıklarını runtime bağımlılıklarından ayırmaktır. Her FROM ifadesi yeni bir aşama başlatır; son aşama yalnızca açıkça COPY --from ile belirttiğiniz şeyleri alır.
# Aşama 1: Composer bağımlılıkları
FROM composer:2 AS vendor
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-scripts
# Aşama 2: Node varlıkları
FROM node:20-alpine AS assets
WORKDIR /app
COPY package.json package-lock.json vite.config.js ./
COPY resources ./resources
RUN npm ci && npm run build
# Aşama 3: Runtime imajı
FROM php:8.3-fpm-alpine
WORKDIR /var/www/html
COPY . .
COPY --from=vendor /app/vendor ./vendor
COPY --from=assets /app/public/build ./public/build
RUN php artisan config:cache && php artisan route:cache
Sonuçlar
Bu yapıyı uyguladıktan sonra imaj 1.2 GB'dan 180 MB'a indi — yüzde 85 küçülme. Docker katman önbelleği sayesinde vendor ve asset aşamaları yalnızca ilgili lock dosyaları değiştiğinde yeniden build aldığından, build süresi aşağı yukarı aynı kaldı.
Dikkat Edilmesi Gerekenler
- Tam uygulama bir araya gelmeden artisan komutlarının çalışmasını önlemek için vendor aşamasında
composer install --no-scriptskullanın .envdosyasını imaja kopyalamayın — ortam değişkenlerini runtime'da enjekte edin- Runtime aşamasındaki
php artisan config:cachekonfigürasyonu build sırasında sabitler; CI ortamınızda tüm gerekli ortam değişkenlerinin tanımlı olduğundan emin olun