Build Multi-Tahap dan Optimasi
Perkecil image dan pisahkan proses build dari waktu berjalan.
Build Multi-Tahap dan Optimasi adalah pelajaran PHP Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar PHP Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus PHP Academy mencakup 4 pelajaran total.
Mengapa Multi-Tahap
Citra satu tahap membawa Composer, dependensi pembangunan, header pengembangan, dan folder tests/ ke produksi. Pembangunan multi-tahap memungkinkan Anda melakukan kompilasi atau pemasangan dalam tahap pembangun yang besar dan menyalin hanya artefak yang sudah selesai ke tahap waktu proses yang ramping.
Hasilnya: citra lebih kecil, permukaan serangan lebih sempit, pengunduhan lebih cepat, dan tidak ada kompiler yang dikirim ke produksi.
Tahap Bernama
Setiap FROM ... AS name memulai tahap baru. Tahap berikutnya dapat menyalin berkas dari tahap sebelumnya dengan COPY --from=name. Hanya tahap terakhir yang menjadi citra Anda; tahap perantara dibuang, tetapi tetap disimpan dalam tembolok.
# 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 . .Memisahkan Dependensi Pembangunan
Kompilasi ekstensi memerlukan autoconf, gcc, dan header pengembangan — semuanya tidak termasuk dalam waktu proses. Gunakan penginstal dalam tahap pembangun, lalu salin berkas .so yang telah dikompilasi dan berkas ini conf.d yang sesuai ke tahap waktu proses yang bersih.
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/Urutan Penyimpanan Lapisan
Docker menyimpan lapisan dalam tembolok dari atas ke bawah dan membatalkan semua lapisan di bawah lapisan yang berubah. Urutkan dari yang paling jarang hingga yang paling sering berubah:
- Basis + ekstensi (jarang)
composer.lock+ pemasangan (sesekali)- Kode sumber aplikasi (setiap commit)
- Pembuatan pemuat otomatis (setiap commit)
Artinya, perubahan yang hanya menyentuh kode dapat menggunakan kembali seluruh lapisan dependensi yang tersimpan.
# 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 --optimizePemasangan Tembolok BuildKit
Dengan BuildKit (DOCKER_BUILDKIT=1), Anda dapat memasang tembolok persisten yang tetap ada di antara pembangunan tanpa masuk ke dalam citra. Ini sangat cocok untuk tembolok global Composer, sehingga pembangunan berulang tidak perlu mengunduh ulang paket.
# 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-distMengukur Ukuran Citra
Periksa perincian lapisan untuk menemukan ruang berlebih. docker history menunjukkan ukuran yang ditambahkan setiap instruksi; alat seperti dive menunjukkan ruang yang terbuang. Tujuannya adalah tahap waktu proses tanpa kompiler, tanpa Composer, dan tanpa dependensi pengembangan.
# 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:latestMemangkas Tahap Terakhir
Tahap waktu proses NOT boleh berisi Composer, skrip penginstal ekstensi, atau kumpulan pengujian Anda. Salin vendor dan kode sumber dari tahap pembangun; jangan pernah menjalankan composer di tahap terakhir. Hapus penginstal setelah digunakan jika Anda harus menjalankannya di sana.
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"]Batasan Distroless / Scratch
PHP tidak dapat berjalan pada scratch yang benar-benar kosong — PHP memerlukan libc dan pustaka bersama. Batas praktis minimumnya adalah alpine (musl) atau Debian minimal bergaya distroless. Alpine paling kecil, tetapi waspadai pustaka asli yang mengharapkan glibc; jika Anda mengalami kesalahan segmentasi dengan NSS/ICU, beralihlah ke 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-bookwormMenargetkan Tahap
Satu Dockerfile dapat melayani pengembangan dan produksi melalui --target. Tambahkan tahap dev di atas tahap waktu proses yang memasukkan kembali dependensi pengembangan Composer dan Xdebug; gunakan --target=runtime untuk produksi dan --target=dev secara lokal.
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 .Menalar Ukuran Lapisan
Model mental singkat membantu Anda memprediksi perilaku tembolok. Cuplikan CLI ini menyimulasikan kesalahan umum berupa pertumbuhan lapisan tanpa batas dibandingkan pertumbuhan yang dibatasi, sekaligus menunjukkan alasan pembersihan perlu digabungkan ke dalam RUN yang sama.
<?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";
?>Gabungkan dan Bersihkan dalam Satu RUN
Setiap RUN adalah lapisan; menghapus berkas pada lapisan berikutnya tidak mengecilkan citra karena lapisan sebelumnya masih menyimpan bita tersebut. Pasang, gunakan, dan bersihkan dalam satu RUN agar berkas sementara tidak pernah dicatat ke dalam citra.
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/*Pemeriksaan Singkat
Mengapa dependensi pembangunan harus dihapus dalam RUN yang sama saat dependensi tersebut dipasang?
Rangkuman
Pembangunan multi-tahap menjauhkan kompiler dan dependensi pengembangan dari produksi. Anda telah mempelajari cara: memberi nama pada tahap dan menyalin artefak dengan COPY --from, mengurutkan lapisan dari yang paling jarang hingga paling sering berubah untuk penyimpanan dalam tembolok, menggunakan pemasangan tembolok BuildKit untuk Composer, mengukur ukuran dengan docker history/dive, memilih alpine atau glibc secara sengaja, menargetkan tahap pengembangan atau produksi, serta menggabungkan pemasangan dan pembersihan dalam satu RUN.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Build Multi-Tahap dan Optimasi” gratis?
Ya — teks lengkap “Build Multi-Tahap dan Optimasi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus PHP Academy, upgrade ke CoddyKit PRO. Kursus PHP Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Build Multi-Tahap dan Optimasi”?
Perkecil image dan pisahkan proses build dari waktu berjalan. Kamu berlatih PHP Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai PHP Academy?
Tidak diperlukan pengalaman sebelumnya. PHP Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Build Multi-Tahap dan Optimasi” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran PHP Academy ini?
Ya. Setiap pelajaran PHP Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Membuat Aplikasi PHP Menjadi Kontainer
- Build Multi-Tahap dan Optimasi
- Docker Compose untuk Tumpukan Lokal
- CI/CD dengan GitHub Actions