PHP #
PHP adalah salah satu bahasa paling umum di dunia web, tetapi juga salah satu yang paling sering disalahgunakan di Docker. Image PHP di production sering:
- Ukuran > 500 MB
- Penuh tool build
- Bercampur antara dev & runtime
Padahal, PHP bisa dibuat sangat ramping, aman, dan layak production, setara dengan Node.js, Python, bahkan mendekati Go—jika diperlakukan dengan benar.
Artikel ini membahas strategi Docker image PHP yang kecil dan production-grade, dengan pendekatan engineering, bukan sekadar tutorial php:apache.
Realita Ukuran Docker Image PHP #
Tanpa Strategi #
| Setup | Ukuran Image |
|---|---|
| php:apache | 600–800 MB |
| php:fpm + debian | 400–600 MB |
Dengan Strategi yang Benar #
| Setup | Ukuran Image |
|---|---|
| php:fpm-alpine | 120–200 MB |
| Multi-stage + slim | 90–150 MB |
| Distroless PHP | 60–100 MB ⭐ |
Masalah Utama PHP di Docker #
1. PHP = Runtime + Web Server + Extension #
Tanpa kontrol:
- Apache
- PHP CLI
- build tools
- extension compiler
Semuanya ikut ke runtime.
2. Extension PHP Membengkakkan Image #
Contoh:
pdo_pgsqlgdintlzip
Semua butuh OS library.
3. Composer Bocor ke Runtime #
- Composer
- cache
- dev dependency
Padahal tidak dibutuhkan saat runtime.
Prinsip Utama Image PHP Production #
Runtime PHP hanya berisi PHP-FPM + extension production + aplikasi.
Yang harus mati di runtime:
- gcc / make
- composer
- dev dependency
- test & tooling
Strategi 1: PHP-FPM + Alpine (Fondasi) #
FROM php:8.3-fpm-alpine AS base
WORKDIR /app
RUN apk add --no-cache \
libpq \
icu-libs \
oniguruma
RUN docker-php-ext-install pdo pdo_pgsql
COPY . .
CMD ["php-fpm"]
Ukuran: 120–200 MB.
Strategi 2: Multi-stage Build dengan Composer #
FROM composer:2 AS builder
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader
FROM php:8.3-fpm-alpine
WORKDIR /app
RUN apk add --no-cache libpq icu-libs
RUN docker-php-ext-install pdo pdo_pgsql
COPY --from=builder /app /app
COPY . .
CMD ["php-fpm"]
Ukuran: 90–150 MB.
Strategi 3: Distroless PHP (Advanced) #
PHP tidak punya distroless resmi, tapi bisa:
FROM php:8.3-cli-alpine AS builder
WORKDIR /app
RUN apk add --no-cache $PHPIZE_DEPS libpq-dev
RUN docker-php-ext-install pdo pdo_pgsql
COPY . .
FROM gcr.io/distroless/base-debian12
WORKDIR /app
COPY --from=builder /usr/local /usr/local
COPY --from=builder /app /app
ENV PATH="/usr/local/bin:$PATH"
CMD ["php", "public/index.php"]
Ukuran: 60–100 MB.
Trade-off:
- debugging sulit
- harus paham dependency extension
Web Server: Jangan Campur #
Best practice:
- PHP-FPM container
- Nginx container terpisah
Manfaat:
- image lebih kecil
- scaling independen
Optimasi Composer #
composer install \
--no-dev \
--classmap-authoritative \
--no-scripts
Hapus cache:
rm -rf ~/.composer/cache
PHP Framework (Laravel / Symfony) #
Lakukan di build stage:
- config cache
- route cache
- view compile
Runtime tidak butuh:
- node
- npm
Security & Production Readiness #
Non-root User #
Gunakan user custom atau distroless base.
Logging #
- STDERR/STDOUT
- JSON log
Healthcheck #
Gunakan HTTP endpoint.
Perbandingan Strategi #
| Strategi | Ukuran | Kompleksitas | Rekomendasi |
|---|---|---|---|
| php:fpm-alpine | Sedang | Rendah | Default |
| Multi-stage | Kecil | Menengah | Production |
| Distroless | Sangat kecil | Tinggi | Mature team |
Kapan Strategi Mana Digunakan? #
| Kondisi | Pilihan |
|---|---|
| Laravel API | multi-stage |
| High security | distroless |
| Shared hosting mindset | ❌ |
Penutup #
PHP bukan bahasa legacy di Docker—yang legacy adalah cara memperlakukannya.
Dengan:
- pemisahan build & runtime
- kontrol extension
- disiplin composer
PHP bisa:
- image <150 MB
- aman di Kubernetes
- scalable untuk sistem modern
Docker image PHP besar bukan takdir—itu kebiasaan lama yang belum dibuang.