← Semua pembelajaran / Laravel Nol → Enterprise
Fase 8 · FrankenPHP & RoadRunner

FrankenPHP — pengantar

FrankenPHP bukan proxy di depan PHP — ia adalah web server Caddy dengan interpreter PHP di dalamnya. Konsekuensinya besar: tidak ada Nginx, tidak ada FPM, tidak ada soket di antara keduanya.

Sumber asli frankenphp.dev Resmi Rangkuman ~6 menit baca

Intisari

  • Dibangun di atas Caddy: HTTPS otomatis, HTTP/2 dan HTTP/3, kompresi, berkas statis — semuanya bawaan.
  • PHP tertanam sebagai pustaka; permintaan ditangani sebagai utas, bukan proses terpisah.
  • Bisa dipakai sebagai pengganti langsung PHP-FPM (mode klasik), atau dinyalakan ke worker mode.
  • Bisa mengemas seluruh aplikasi jadi satu berkas biner yang bisa dijalankan tanpa PHP terpasang.
  • Sejak 2025 ia menjadi proyek resmi di bawah organisasi PHP.

Perbedaan arsitektur

TUMPUKAN KLASIK
  internet → Nginx (TLS, statis) → soket → PHP-FPM (proses per permintaan)
             ↑ dua proses, dua konfigurasi, satu soket di antaranya

FRANKENPHP
  internet → FrankenPHP (TLS, statis, PHP)
             ↑ satu proses, satu konfigurasi
KemampuanNginx + PHP-FPMFrankenPHP
TLS otomatis (Let's Encrypt)Perlu CertbotBawaan
HTTP/2YaYa
HTTP/3 (QUIC)Perlu build khususBawaan
Kompresi Brotli & ZstandardPerlu modulBawaan
Berkas statisYaYa
Early hints (103)TidakBawaan
Jumlah proses yang dijagaDuaSatu
Model konkurensiProsesUtas

Menjalankan pertama kali

# Docker: cukup pasang proyekmu di /app
docker run -p 80:80 -p 443:443 -p 443:443/udp -v $PWD:/app dunglas/frankenphp
# Biner mandiri, dari folder proyek
frankenphp run
frankenphp php-server --root public/

Caddyfile

{
	frankenphp
}

portal.test {
	root public/
	encode zstd br gzip

	php_server {
		try_files {path} index.php
	}
}

Blok pertama menyalakan modul FrankenPHP; blok kedua mendefinisikan satu situs. Nama domain di sana bukan sekadar label — Caddy memakainya untuk meminta sertifikat TLS secara otomatis. Menuliskan :80 sebagai gantinya mematikan HTTPS, yang tepat kalau ada load balancer yang sudah menanganinya.

Dua mode

Mode klasikWorker mode
Bootstrap aplikasiTiap permintaanSekali per utas worker
Perubahan kode aplikasiTidak perluPerlu kode yang bersih dari kebocoran state
Perlu restart saat deployTidakYa
KecepatanSetara PHP-FPMJauh lebih cepat

Ini keunggulan adopsi yang nyata. Kamu bisa mengganti Nginx + PHP-FPM dengan FrankenPHP mode klasik hari ini, tanpa mengubah satu baris kode aplikasi, dan langsung mendapat HTTPS otomatis, HTTP/3, dan satu proses yang lebih sederhana. Worker mode bisa dinyalakan belakangan sebagai langkah terpisah — dua perubahan besar tidak perlu dilakukan sekaligus.

Konkurensi berbasis utas

{
	frankenphp {
		num_threads 16          # utas yang selalu ada
		max_threads 48          # batas atas saat lalu lintas melonjak
	}
}

Karena satuannya utas dan bukan proses, jejak memorinya lebih kecil daripada jumlah proses FPM yang setara. Konsekuensinya: PHP harus dikompilasi dalam mode thread-safe (ZTS) — dan setiap ekstensi PHP yang kamu pakai juga harus aman terhadap utas. Ini poin yang perlu diperiksa kalau aplikasimu bergantung pada ekstensi yang tidak umum.

Fitur yang tidak ada di tempat lain

FiturGunanya
Biner mandiriKemas aplikasi + PHP + server jadi satu berkas yang bisa dijalankan
MercureServer-sent events untuk pembaruan real-time, tanpa layanan tambahan
Early hintsKirim 103 supaya browser mulai mengunduh aset sebelum HTML siap
Kumpulan utas terpisahEndpoint lambat tidak menghabiskan seluruh kapasitas
Ekosistem modul CaddyRate limiting, autentikasi, dan proxy tanpa lapisan tambahan

Catatan tentang Alpine. Dokumentasi FrankenPHP secara eksplisit menyarankan menghindari musl di produksi: PHP diketahui lebih lambat saat ditautkan ke musl dibandingkan glibc, terutama dalam mode thread-safe yang dibutuhkan FrankenPHP — dan sebagian bug hanya muncul di musl. Pakai image berbasis Debian. Ini kebalikan dari kebiasaan "pilih Alpine supaya image kecil", dan penting untuk diketahui sebelum menulis Dockerfile di Fase 9.

Latihan: jalankan aplikasimu dengan docker run … dunglas/frankenphp dalam mode klasik, tanpa mengubah satu baris kode. Pastikan halaman terbuka, lalu jalankan curl -sI --http3 https://localhost/ dan lihat bahwa HTTP/3 memang aktif.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.