Panduan lengkap instalasi FrankenPHP: static binary, install script, Homebrew, paket deb/rpm/apk, dan image Docker. Dilanjutkan dengan konfigurasi Caddyfile pertama — root public, php_server, dan routing dasar — lalu menjalankannya dengan frankenphp run.

Setelah di episode 2 kita memahami arsitektur — Caddy + PHP-ZTS dalam satu proses, classic vs worker — kini saatnya hands-on: menginstall FrankenPHP dan menyusun Caddyfile pertama. Pilih metode instalasi yang paling cocok dengan environment kalian, lalu pelajari dasar-dasar Caddyfile yang akan kita pakai di seluruh series ini.
Mengapa topik ini penting? Karena FrankenPHP tidak mengikuti pola instalasi web server biasa. Ia menawarkan banyak jalur — static binary, package manager, Docker — dan masing-masing punya trade-off yang berbeda untuk pengelolaan update dan ekstensi. Memahami pilihan sejak awal akan menyelamatkan kalian dari "installed version mismatch" di episode 15 nanti.
Cara tercepat dan paling portabel. Binary statis Linux berjalan di distribusi mana pun tanpa dependensi tambahan:
curl https://frankenphp.dev/install.sh | shUntuk Windows, gunakan PowerShell:
irm https://frankenphp.dev/install.ps1 | iexHasilnya adalah binary frankenphp yang membundel PHP 8.5 dan sebagian besar ekstensi populer. Verifikasi:
frankenphp version
frankenphp php-cli -vbrew install dunglas/frankenphp/frankenphpHomebrew adalah pilihan paling nyaman di macOS: update dengan brew upgrade, dan bisa dijalankan sebagai service via brew services start dunglas/frankenphp/frankenphp.
Maintainer resmi menyediakan repository untuk sistem apt, dnf, dan apk. Untuk Debian/Ubuntu dengan PHP 8.5:
VERSION=85
sudo curl https://pkg.henderkes.com/api/packages/${VERSION}/debian/repository.key -o /etc/apt/keyrings/static-php${VERSION}.asc
echo "deb [signed-by=/etc/apt/keyrings/static-php${VERSION}.asc] https://pkg.henderkes.com/api/packages/${VERSION}/debian php-zts main" | sudo tee -a /etc/apt/sources.list.d/static-php${VERSION}.list
sudo apt update
sudo apt install frankenphpPaket ini sekaligus menyediakan service systemd (sudo systemctl start frankenphp), file config di /etc/frankenphp/Caddyfile, dan dukungan ekstensi via sudo apt install php-zts-<ekstensi>.
Tip
Beda lokasi konfigurasi per metode: Docker dan paket distro membaca /etc/frankenphp/Caddyfile; static binary membaca Caddyfile di direktori kerja saat frankenphp run dijalankan. Ini sering menjadi sumber kebingungan pertama kali.
Image resmi dunglas/frankenphp berbasis image PHP resmi (Debian dan Alpine). Cara paling cepat mencoba:
docker run \
-v .:/app/public \
-p 80:80 -p 443:443 -p 443:443/udp \
dunglas/frankenphpMount direktori berisi index.php ke /app/public, lalu buka https://localhost. Kita bedah Docker secara mendalam di episode 19.
Caddyfile adalah bahasa konfigurasi FrankenPHP. Konsep dasarnya sederhana: site block (hostname yang dilayani) berisi directive. Contoh paling minimal:
localhost
root * public/
php_serverJalankan dengan:
frankenphp runMari bedah tiga baris di atas:
localhost — site block: FrankenPHP mendengarkan untuk hostname localhost. Tanpa site block, php_server di level global juga valid (contoh Caddyfile php_server tunggal).root * public/ — direktori web root. Tanda * adalah matcher yang berlaku untuk semua path.php_server — directive FrankenPHP yang menggabungkan eksekusi PHP, file server, dan try_files.Caddyfile mendukung matcher untuk routing. Contoh memisahkan rute API dan halaman:
localhost
root * public/
@api path /api/*
php @api public/index.php
php_serverDi sini semua request /api/* diteruskan langsung ke index.php (lewati cek file statis), sedangkan request lainnya ditangani php_server biasa yang tetap melayani aset statis.
Warning
Urutan directive di Caddyfile berarti. Directives diproses dalam urutan yang sudah ditentukan Caddy (bukan urutan penulisan), jadi matcher dengan lingkup lebih spesifik harus dirancang agar tidak "menelan" request lain. Uji setiap perubahan dengan frankenphp validate dulu.
frankenphp GlobalUntuk opsi di level server, gunakan global option frankenphp di blok { } paling atas:
{
frankenphp {
php_ini memory_limit 256M
php_ini max_execution_time 30
num_threads 8
}
}
localhost {
root * public/
php_server
}php_ini memungkinkan kalian mengatur directive php.ini langsung dari Caddyfile — padanan php_value/php_admin_value di PHP-FPM.
Dua directive Caddy yang akan selalu kalian pakai di produksi:
localhost
encode zstd br gzip
log
root * public/
php_serverencode zstd br gzip — kompresi response dengan prioritas Zstandard, Brotli, lalu gzip.log — mengaktifkan access log.Sebelum deploy, validasi Caddyfile tanpa menjalankan server:
frankenphp validate --config CaddyfileJika output-nya Valid configuration, kalian aman. Lalu jalankan server dan uji:
frankenphp run
curl -I http://localhostResponse 200 OK plus header Content-Encoding (jika encode aktif) menandakan semuanya bekerja.
| Metode | Kelebihan | Kekurangan |
|---|---|---|
| Static binary | Portabel, tanpa dependensi, PHP 8.5 bawaan | Ekstensi tambahan harus di-embed saat build |
| Homebrew | Nyaman di macOS, mudah update | Bergantung pada Homebrew |
| deb/rpm/apk | Service systemd, ekstensi via php-zts-* | Lokasi config berbeda dari binary |
| Docker | Reproducible, cocok CI/CD | Perlu pengetahuan Docker |
Pada episode 3 ini, kalian telah menginstall FrankenPHP dan menyusun Caddyfile pertama.
Inti yang harus dibawa pulang:
frankenphp run membaca Caddyfile di direktori kerja (khusus static binary).root * public/ + php_server adalah fondasinya.frankenphp validate sebelum menjalankan konfigurasi baru.encode dan log sebaiknya aktif sejak awal.Di episode 4 selanjutnya kita akan membahas PHP server classic vs PHP worker — kapan memakai php_server polos, kapan menambahkan subdirective worker, perbedaan FRANKENPHP_CONFIG, serta trade-off performa dan kompatibilitas antara kedua mode. Sampai jumpa di episode 4!