โ† Semua pembelajaran / Laravel Nol โ†’ Enterprise
Fase 8 ยท FrankenPHP & RoadRunner

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.

Sumber asli frankenphp.dev Resmi Rangkuman ~6 menit baca

Intisari

  • Docker: pasang proyek ke /app dan selesai โ€” mode klasik berjalan tanpa konfigurasi.
  • Lokal: unduh biner, tulis Caddyfile dengan root public/, jalankan frankenphp run.
  • Worker mode lewat Octane: octane:install --server=frankenphp lalu octane: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:frankenphpDefaultCatatan
--host127.0.0.1Di kontainer wajib 0.0.0.0
--port8000
--admin-port2019API admin Caddy โ€” jangan diekspos publik
--workersautoSetel eksplisit di kontainer dengan CPU terbatas
--max-requests500Restart berkala; penawar kebocoran memori
--caddyfileBawaan OctaneTunjuk ke Caddyfile sendiri saat butuh kendali penuh
--httpsMatiSertifikat otomatis; tidak perlu kalau ada ALB di depan
--watchMatiHanya 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

  1. $request->ip() dan skema HTTPS benar โ€” trusted proxy sudah diatur (Fase 1).
  2. Unggahan besar tidak ditolak โ€” periksa upload_max_filesize dan batas ukuran badan permintaan.
  3. Semua ekstensi PHP yang kamu pakai aman terhadap utas.
  4. Log keluar ke stdout/stderr, bukan ke berkas di dalam kontainer.
  5. 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.