FrankenPHP untuk Laravel
Menjalankan Laravel di FrankenPHP bisa sesederhana memasang folder proyek ke dalam kontainer. Yang perlu diputuskan adalah apakah kamu berhenti di situ, atau melanjutkan ke worker mode lewat Octane.
Intisari
- Docker: pasang proyek ke
/appdan selesai โ mode klasik berjalan tanpa konfigurasi. - Lokal: unduh biner, tulis
Caddyfiledenganroot public/, jalankanfrankenphp run. - Worker mode lewat Octane:
octane:install --server=frankenphplaluoctane:frankenphp. - Octane mengunduh biner FrankenPHP-nya sendiri saat pertama kali dipakai.
- Aplikasi Laravel bisa dikemas jadi satu biner; kalau begitu, atur
LARAVEL_STORAGE_PATH.
Cara 1 โ Docker, tanpa konfigurasi
docker run -p 80:80 -p 443:443 -p 443:443/udp -v $PWD:/app dunglas/frankenphp
Dijalankan dari folder proyek Laravel, ini sudah cukup. Image resminya sudah tahu bahwa aplikasi PHP tinggal di
/app dengan web root di public/.
Cara 2 โ biner lokal
{
frankenphp
}
localhost {
root public/
encode zstd br gzip
php_server {
try_files {path} index.php
}
}
frankenphp run
Cara 3 โ worker mode lewat Octane
composer require laravel/octane
php artisan octane:install --server=frankenphp
php artisan octane:frankenphp
Opsi octane:frankenphp | Default | Catatan |
|---|---|---|
--host | 127.0.0.1 | Di kontainer wajib 0.0.0.0 |
--port | 8000 | |
--admin-port | 2019 | API admin Caddy โ jangan diekspos publik |
--workers | auto | Setel eksplisit di kontainer dengan CPU terbatas |
--max-requests | 500 | Restart berkala; penawar kebocoran memori |
--caddyfile | Bawaan Octane | Tunjuk ke Caddyfile sendiri saat butuh kendali penuh |
--https | Mati | Sertifikat otomatis; tidak perlu kalau ada ALB di depan |
--watch | Mati | Hanya untuk pengembangan |
--log-level | โ | Sebutkan eksplisit untuk mendapat log JSON terstruktur |
Sebutkan --log-level di produksi. Dengan opsi itu, FrankenPHP menghasilkan log JSON
terstruktur โ yang bisa langsung diurai CloudWatch Logs Insights tanpa parser tambahan. Tanpa itu, kamu akan
menghabiskan waktu menulis pola regex untuk log yang seharusnya sudah terstruktur sejak awal.
Caddyfile sendiri untuk worker mode
{
frankenphp {
num_threads 16
max_threads 48
worker {
file /app/public/frankenphp-worker.php
num 8
env APP_ENV production
max_consecutive_failures 10
}
}
# API admin hanya dari dalam kontainer
admin localhost:2019
}
:8000 {
root /app/public
encode zstd br gzip
# Aset statis dilayani langsung, tidak menyentuh PHP sama sekali
@statis path /build/* /favicon.ico /robots.txt
file_server @statis
php_server {
try_files {path} index.php
}
}
Memisahkan aset statis itu penting di worker mode. Secara default php_server memeriksa
keberadaan berkas sebelum menyerahkan ke PHP โ satu operasi filesystem per permintaan. Dengan matcher
@statis, permintaan aset ditangani file server dan permintaan lain langsung ke worker, tanpa
pemeriksaan berkas sama sekali.
Kumpulan utas terpisah untuk endpoint lambat
portal.test {
php_server {
root /app/public
worker index.php {
match /ekspor/* # endpoint lambat punya kolamnya sendiri
num 1
max_threads 8
}
worker index.php {
match * # sisanya tidak terpengaruh
num 4
max_threads 32
}
}
}
Ini fitur yang tidak punya padanan langsung di tempat lain. Kalau ada satu endpoint yang memanggil layanan luar lambat, tanpa pemisahan ini ia bisa menghabiskan seluruh utas dan membuat halaman lain ikut mati. Dengan kolam terpisah, dampaknya terkurung โ mirip bulkhead pada kapal.
Laravel sebagai satu biner
# static-build.Dockerfile
FROM --platform=linux/amd64 dunglas/frankenphp:static-builder-gnu
WORKDIR /go/src/app/dist/app
COPY . .
RUN rm -Rf tests/
RUN cp .env.example .env
RUN sed -i'' -e 's/^APP_ENV=.*/APP_ENV=production/' -e 's/^APP_DEBUG=.*/APP_DEBUG=false/' .env
RUN composer install --ignore-platform-reqs --no-dev -a
WORKDIR /go/src/app/
RUN EMBED=dist/app/ ./build-static.sh
frankenphp php-cli artisan optimize
frankenphp php-cli artisan migrate
frankenphp php-server
Kalau memakai biner mandiri, atur LARAVEL_STORAGE_PATH. Setiap versi biner diekstrak ke
folder sementara yang berbeda, jadi storage/ bawaan akan berpindah tempat setiap kali โ
membawa serta log, cache, dan berkas unggahan. Arahkan ke folder di luar direktori sementara. Untuk deploy
berbasis kontainer, biner mandiri jarang diperlukan; ia bersinar untuk distribusi aplikasi ke lingkungan yang
tidak punya PHP.
Yang perlu diperiksa setelah pindah
$request->ip()dan skema HTTPS benar โ trusted proxy sudah diatur (Fase 1).- Unggahan besar tidak ditolak โ periksa
upload_max_filesizedan batas ukuran badan permintaan. - Semua ekstensi PHP yang kamu pakai aman terhadap utas.
- Log keluar ke
stdout/stderr, bukan ke berkas di dalam kontainer. - Endpoint health check merespons tanpa menyentuh database.
Latihan: jalankan php artisan octane:frankenphp --workers=4 --log-level=info, lalu
bandingkan waktu respons /ukur dengan angka PHP-FPM yang kamu catat di awal fase. Setelah itu
tulis Caddyfile sendiri yang memisahkan /build/* ke file server dan pastikan aset tetap terlayani.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.