Laravel dari Nol sampai Enterprise
Dari rute pertama sampai aplikasi yang berjalan di produksi untuk banyak orang β dengan izin yang benar, query yang tidak menghabiskan database, deploy tanpa jeda, dan biaya yang bisa dijelaskan.
Dua fase terakhir sebelum capstone menjawab pertanyaan yang paling sering ditanyakan tapi jarang dibahas tuntas: FrankenPHP atau RoadRunner, dan bagaimana persisnya semua ini di-deploy di AWS.
- Durasi
- ~16 minggu
- Beban
- ~8 jam/minggu
- Prasyarat
- Pernah ngoding, paham HTTP
- Target akhir
- Aplikasi produksi di AWS
Untuk siapa roadmap ini
"Dari nol" di sini berarti nol Laravel, bukan nol pemrograman. Kamu diasumsikan sudah pernah menulis kode di bahasa apa pun dan paham dasar HTTP. PHP modern dibahas ringkas di Fase 0 β cukup untuk membaca seluruh kode di roadmap ini, tanpa berpura-pura ini kursus PHP.
Kalau kamu belum pernah ngoding sama sekali, mulai dari Python Dasar untuk Pemula dulu. Konsepnya β variabel, percabangan, fungsi, struktur data β sama di semua bahasa, dan jauh lebih mudah dipelajari tanpa framework di atasnya.
Yang sengaja dilewati
| Topik | Alasan |
|---|---|
| PHP dari nol (sintaks dasar, OOP dasar) | Diasumsikan bisa ngoding; Fase 0 cuma memetakan perbedaannya |
| Laravel 10 ke bawah | Struktur kerangkanya berbeda cukup jauh sampai bisa menyesatkan |
| jQuery dan pola frontend lama | Blade, Livewire, atau Inertia menutup kebutuhannya |
| Terraform & CDK | Konsep AWS-nya yang diajarkan; alat IaC bisa menyusul |
| Kubernetes | ECS Fargate cukup, dan jauh lebih sedikit yang harus dioperasikan |
| Swoole | Dibahas sekilas; fokusnya FrankenPHP dan RoadRunner sesuai permintaan |
| Microservice | Dibahas kenapa biasanya bukan jawabannya di Fase 10 |
Bentuk roadmap ini
| Bagian | Fase | Menjawab |
|---|---|---|
| Dasar framework | 0 β 2 | Bagaimana Laravel bekerja, dan bagaimana bicara ke database |
| Cara menulis aplikasi nyata | 3 β 6 | Arsitektur, keamanan, API, dan bukti bahwa semuanya masih benar |
| Membuatnya cepat | 7 β 8 | Query, cache, CDN, lalu worker mode |
| Menjalankannya untuk orang lain | 9 β 10 | AWS, deploy tanpa jeda, dan bertahan bertahun-tahun |
Urutannya disengaja. Fase 8 dan 9 adalah bagian yang paling sering dicari duluan β tapi worker mode di atas kode yang masih punya query N+1 hanya memindahkan masalah, dan deploy ke AWS tanpa tes hanya mempercepat penyebaran bug. Jangan lompat ke Fase 8.
Fondasi PHP & Tooling
Tujuan: punya aplikasi Laravel yang berjalan di laptopmu, dan bisa membaca kode PHP modern tanpa tersandung sintaks.
Perhatian: banyak tutorial Laravel masih menyuruhmu membuka app/Http/Kernel.php.
File itu tidak ada lagi sejak Laravel 11 β konfigurasinya pindah ke bootstrap/app.php.
Kalau sebuah panduan menyebut berkas yang tidak kamu punya, cek dulu versi Laravel yang ditulisnya.
Setup sekali jalan
# PHP + Composer + installer sekaligus
/bin/bash -c "$(curl -fsSL https://php.new/install/linux/8.5)"
laravel new portal
cd portal
npm install && npm run build
composer run dev # server + queue listener + vite, satu perintah
Empat hal yang harus benar sejak hari pertama
| Hal | Kenapa |
|---|---|
Web root menunjuk ke public/ | Kalau tidak, .env bisa diunduh siapa saja |
env() hanya di dalam config/ | Setelah config:cache, di tempat lain ia null |
| Database yang sama dengan produksi | Perbedaan SQLite dan MySQL bocor di tempat-tempat kecil |
declare(strict_types=1) | Jauh lebih murah dinyalakan sekarang daripada nanti |
Materi
-
PHP modern untuk pendatangResmiPHP 8.3+ bukan PHP yang kamu dengar ceritanya. Tipe, enum, readonly, dan constructor promotion β bahan yang dipakai Laravel setiap hari.www.php.netBaca rangkuman β
-
Composer β dependensi & autoloadResminpm-nya PHP, plus satu tugas tambahan yang tidak dilakukan npm: mengurus autoload kelas.getcomposer.orgBaca rangkuman β
-
Memasang LaravelResmiDari
laravel newsampai halaman pertama terbuka β plus keputusan database yang menentukan sisa minggu ini.laravel.comBaca rangkuman β -
Struktur direktoriResmiPeta folder Laravel β dan alasan kenapa konvensi yang kaku justru mempercepat tim besar.laravel.comBaca rangkuman β
-
Konfigurasi & environmentResmi
.env,config(), dan satu aturan yang kalau dilanggar akan membuat aplikasimu mati begitu di-deploy.laravel.comBaca rangkuman β -
Artisan β CLI LaravelResmiGenerator, penjelajah, dan pintu masuk ke aplikasimu dari terminal. Termasuk Tinker, yang akan kamu pakai tiap hari.laravel.comBaca rangkuman β
Aplikasi Laravel berjalan di laptopmu, kamu bisa menjelaskan apa yang dilakukan
composer install versus composer update, dan kamu tahu kenapa
env() di dalam controller adalah bug yang menunggu produksi.
Request, Routing & Blade
Tujuan: bisa membangun halaman dan form yang lengkap β tervalidasi, tertangani errornya, dan tahu persis apa yang terjadi antara browser menekan Enter dan controller-mu berjalan.
Bentuk yang akan kamu tulis berulang kali
Route::resource('artikel', ArtikelController::class);
public function store(SimpanArtikelRequest $request): RedirectResponse
{
// Sudah tervalidasi DAN terotorisasi sebelum baris ini berjalan.
$artikel = Artikel::create($request->validated());
return redirect()
->route('artikel.show', $artikel)
->with('sukses', 'Artikel tersimpan.');
}
Empat lapis yang harus kamu bedakan
| Lapis | Tugasnya | Bukan tugasnya |
|---|---|---|
| Middleware | Syarat yang berlaku untuk sekelompok rute | Logika bisnis |
| Form Request | Bentuk data boleh masuk atau tidak | Menyimpan data |
| Controller | Menerjemahkan HTTP ke domain dan sebaliknya | Query kompleks, kirim email |
| Blade | Menampilkan | Mengambil data |
Yang membedakan controller sehat dan controller gemuk bukan panjangnya, tapi apakah setiap urusan sudah ada di tempat yang disediakan framework. Validasi punya rumah, otorisasi punya rumah, perhitungan punya rumah. Controller yang tipis adalah akibat, bukan tujuan.
Materi
-
Daur hidup requestResmiApa yang terjadi antara browser menekan Enter dan controller-mu dipanggil. Fondasi untuk memahami Fase 8.laravel.comBaca rangkuman β
-
RoutingResmiMemetakan URL ke kode: parameter, grup, penamaan, dan model binding yang menghapus banyak query manual.laravel.comBaca rangkuman β
-
MiddlewareResmiLapisan yang dilewati setiap permintaan sebelum dan sesudah controller β tempat auth, rate limit, dan tenancy tinggal.laravel.comBaca rangkuman β
-
Controller & responseResmiTempat rute bertemu logika β dan aturan tidak tertulis tentang seberapa banyak yang boleh tinggal di sini.laravel.comBaca rangkuman β
-
HTTP RequestResmiMembaca input, berkas, header, dan identitas pengguna β plus method bertipe yang mencegah bug konversi.laravel.comBaca rangkuman β
-
ValidasiResmiGerbang tempat data tidak dipercaya berubah jadi data yang dipercaya. Form Request membuatnya rapi dan bisa diuji.laravel.comBaca rangkuman β
-
Blade β template engineResmiHTML dengan direktif, dikompilasi jadi PHP biasa. Termasuk komponen dan escaping yang aktif secara default.laravel.comBaca rangkuman β
-
Error & exception handlingResmiApa yang dilihat pengguna saat kode gagal, apa yang tercatat, dan kenapa
APP_DEBUG=truedi produksi itu kebocoran data.laravel.comBaca rangkuman β
Kamu punya CRUD lengkap dengan Form Request, pesan error yang muncul di form, dan satu exception domain yang merender dirinya berbeda untuk HTML dan JSON. Kamu juga bisa menjelaskan kenapa 419 muncul.
Database & Eloquent
Tujuan: bisa memodelkan data dengan benar, dan mengenali sendiri kapan kodemu diam-diam menjalankan lima puluh query untuk satu halaman.
Satu baris yang mengubah kebiasaan tim. Pasang ini di AppServiceProvider sejak hari
pertama β N+1 berubah dari "agak lambat" jadi tes yang gagal:
Model::preventLazyLoading(! app()->isProduction());
Model::preventSilentlyDiscardingAttributes(! app()->isProduction());
Peta keputusan
| Kebutuhan | Pakai | Kenapa |
|---|---|---|
| CRUD satu entitas | Eloquent | Relasi, cast, event, policy ikut bekerja |
| Laporan & agregasi | Query builder | Tidak butuh objek model |
| Update jutaan baris | Query builder | Satu query, bukan sejuta objek |
| Menampilkan relasi di daftar | with() | Dua query, berapa pun barisnya |
| Menghitung relasi | withCount() | Tanpa memuat satu baris pun |
| Uang | integer atau decimal | Jangan pernah float |
Materi
-
Koneksi database & transaksiResmiKonfigurasi koneksi, read/write terpisah, dan transaksi β tiga hal yang menentukan apakah datamu konsisten saat ada masalah.laravel.comBaca rangkuman β
-
Migrasi β skema sebagai kodeResmiRiwayat perubahan database yang bisa dijalankan ulang dari nol β dan aturan main saat tabelnya sudah berisi jutaan baris.laravel.comBaca rangkuman β
-
Query builderResmiSQL yang ditulis sebagai rangkaian method β aman dari injection, dan pilihan yang tepat untuk laporan serta agregasi.laravel.comBaca rangkuman β
-
Eloquent β modelResmiSatu kelas per tabel, dengan konvensi yang menghilangkan konfigurasi. Plus mass assignment β pertahanan yang tidak boleh dilubangi.laravel.comBaca rangkuman β
-
Relasi & masalah N+1ResmiRelasi membuat kode enak dibaca β dan diam-diam menjalankan ratusan query. Ini cara mengenalinya dan mematikannya.laravel.comBaca rangkuman β
-
Cast, accessor & mutatorResmiMenerjemahkan kolom database jadi tipe PHP yang benar β enum, Carbon, array, dan nilai terenkripsi.laravel.comBaca rangkuman β
-
Factory & seederResmiMembuat data uji yang realistis dalam satu baris. Fondasi diam-diam dari seluruh strategi testing di Fase 6.laravel.comBaca rangkuman β
Halaman daftarmu menjalankan jumlah query yang tetap berapa pun jumlah barisnya, kamu punya factory dengan state bernama, dan kamu bisa menulis rencana tiga deploy untuk mengganti nama sebuah kolom di tabel yang sedang dipakai.
Arsitektur Laravel
Tujuan: tahu ke mana sebuah kode seharusnya diletakkan β dan bisa memindahkan pekerjaan berat keluar dari siklus permintaan pengguna.
Fase ini yang membuat sisa roadmap masuk akal. Container menjelaskan kenapa tipe di
parameter itu instruksi, bukan dokumentasi. Queue adalah cara termurah membuat aplikasi
terasa cepat. Dan pemahaman soal singleton versus scoped di sini adalah yang
mencegah kebocoran data antar pengguna saat kita sampai di Fase 8.
| Binding | Umur objek | Untuk |
|---|---|---|
bind | Baru setiap kali | Objek yang menyimpan keadaan |
singleton | Satu, seumur proses | Klien HTTP, koneksi |
scoped | Satu per permintaan | Konteks tenant, keranjang β apa pun yang milik pengguna |
Aturan yang menyelamatkan Fase 8: kalau isi sebuah layanan bergantung pada siapa yang
meminta, ia tidak boleh singleton. Di PHP-FPM kesalahan ini tidak terasa; di worker mode
ia jadi kebocoran data antar pengguna.
Materi
-
Service containerResmiMesin yang membuat objek untukmu berdasarkan tipe. Ini yang membuat controller-mu tidak pernah memanggil
new.laravel.comBaca rangkuman β -
Service providerResmiTempat aplikasimu dirakit. Semua konfigurasi yang berlaku sekali di awal tinggal di sini.laravel.comBaca rangkuman β
-
Facade & helperResmi
Cache::get()terlihat statis, padahal bukan. Cara kerjanya, dan kapan sebaiknya kamu tidak memakainya.laravel.comBaca rangkuman β -
Event & listenerResmiMemisahkan "sesuatu terjadi" dari "apa yang harus dilakukan" β dan kapan pemisahan itu justru menyusahkan.laravel.comBaca rangkuman β
-
Queue & jobResmiMemindahkan pekerjaan berat keluar dari siklus permintaan. Ini fondasi skalabilitas yang paling murah di Laravel.laravel.comBaca rangkuman β
-
Penjadwalan tugasResmiSatu entri cron untuk seluruh jadwal aplikasi β dan pengaman yang wajib begitu servernya lebih dari satu.laravel.comBaca rangkuman β
-
CacheResmiCara termurah membuat aplikasi terasa cepat β dan cara termudah menyajikan data basi kalau invalidasinya asal.laravel.comBaca rangkuman β
Pekerjaan berat sudah pindah ke antrean, job-mu aman kalau dijalankan dua kali, jadwal berkala berjalan
lewat penjadwal Laravel, dan kamu bisa menjelaskan kenapa register() tidak boleh memakai
layanan lain.
Autentikasi & Keamanan
Tujuan: aturan "siapa boleh melakukan apa" tinggal di satu tempat dan tidak bisa dilewati β termasuk oleh orang yang mengetik URL langsung.
Pertahanan berlapis, dari yang paling lemah
| Lapisan | Cukup sendirian? |
|---|---|
@can menyembunyikan tombol | Tidak β cuma urusan tampilan |
Middleware can: di rute | Ya, untuk rute itu |
$this->authorize() di aksi | Ya |
| Query dibatasi kepemilikan | Terkuat β yang bukan miliknya tidak pernah ditemukan |
Yang paling sering bocor bukan autentikasi, melainkan otorisasi objek.
/artikel/7/ulasan/999 yang menampilkan ulasan milik artikel lain, halaman edit yang bisa dibuka
siapa saja karena hanya tombolnya yang disembunyikan, atau binding bersarang tanpa
scopeBindings(). Kelas bug ini tidak akan ditemukan tes yang cuma menguji jalur bahagia.
Yang wajib dibatasi lajunya
| Endpoint | Saran |
|---|---|
| Login | 5 / menit per email + IP |
| Lupa password, registrasi | 3 / menit per IP |
| Pencarian | 30 / menit |
| API publik | 60 / menit per token |
Materi
-
AutentikasiResmiGuard, provider, dan session β tiga konsep yang menjelaskan kenapa
auth()->user()bisa berarti hal berbeda di dua rute.laravel.comBaca rangkuman β -
Starter kitResmiKerangka autentikasi siap pakai β dan pertanyaan yang menentukan pilihannya: seperti apa frontend-mu nanti.laravel.comBaca rangkuman β
-
Otorisasi β gate & policyResmi"Siapa boleh melakukan apa pada objek mana" β ditulis di satu tempat, dipakai di controller, Blade, dan API.laravel.comBaca rangkuman β
-
Sanctum β token APIResmiAutentikasi untuk SPA, aplikasi mobile, dan integrasi pihak ketiga β tanpa kerumitan OAuth2.laravel.comBaca rangkuman β
-
CSRF & kerentanan web umumResmiApa yang sudah dilindungi Laravel secara default, apa yang masih jadi tanggung jawabmu, dan bagaimana cara melubanginya tanpa sadar.laravel.comBaca rangkuman β
-
Hashing & enkripsiResmiKapan data harus di-hash, kapan dienkripsi, dan kenapa keduanya tidak bisa saling menggantikan.laravel.comBaca rangkuman β
-
Rate limitingResmiMembatasi laju permintaan per pengguna, per IP, atau per apa pun β pertahanan pertama terhadap penyalahgunaan dan tagihan tak terduga.laravel.comBaca rangkuman β
Setiap model punya policy, setiap policy punya tes dari kedua sisi, rute login dibatasi lajunya,
dan kamu bisa menjelaskan kenapa endpoint webhook-mu memakai hash_equals().
API & Frontend
Tujuan: bentuk keluaran API jadi keputusan yang ditulis, dan kamu bisa memilih pendekatan frontend dengan alasan yang bisa dijelaskan.
Memilih pendekatan frontend
| Blade | Livewire | Inertia | |
|---|---|---|---|
| Bahasa | PHP | PHP | React / Vue |
| Interaksi | Muat ulang halaman | Permintaan ke server | State di klien |
| Beban server per interaksi | β | Lebih tinggi | Lebih rendah |
| Bisa di-cache penuh di CDN | Ya | Tidak | Tidak |
| SEO | Bawaan | Bawaan | Perlu SSR |
| Paling cocok untuk | Halaman baca publik | Panel admin, form | Antarmuka kaya |
Tidak perlu memilih satu untuk seluruh aplikasi. Pola yang paling sehat untuk situs bertrafik baca tinggi: halaman publik memakai Blade statis yang bisa disajikan penuh dari CDN, dengan komponen Livewire hanya di bagian yang memang interaktif β pencarian, komentar. Panel admin boleh jadi SPA penuh; ia dipakai sedikit orang dan tidak perlu di-cache.
Paginasi: pilihan yang menentukan saat data membesar
paginate | simplePaginate | cursorPaginate | |
|---|---|---|---|
| Query per halaman | 2 | 1 | 1 |
| Biaya di halaman jauh | Naik terus | Naik terus | Tetap |
| Tahan data baru masuk | Tidak | Tidak | Ya |
| Untuk | Tabel admin | Daftar biasa | Umpan, API |
Materi
-
API ResourceResmiLapisan yang memisahkan bentuk database dari bentuk API β supaya menambah kolom tidak diam-diam mengubah kontrak publikmu.laravel.comBaca rangkuman β
-
PaginasiResmiTiga jenis paginasi dengan biaya yang sangat berbeda β dan kenapa
paginate()jadi mahal di tabel besar.laravel.comBaca rangkuman β -
HTTP clientResmiMemanggil API luar dengan timeout, retry, dan tiruan untuk tes β tiga hal yang selalu terlupa di klien buatan sendiri.laravel.comBaca rangkuman β
-
Vite & aset frontendResmiKompilasi CSS dan JavaScript, dengan nama berkas ber-hash yang membuat cache selamanya jadi aman.laravel.comBaca rangkuman β
-
LivewireResmiKomponen interaktif yang ditulis dalam PHP. Tanpa API, tanpa state ganda β dengan konsekuensi yang perlu kamu tahu.livewire.laravel.comBaca rangkuman β
-
Inertia β React/Vue tanpa APIResmiSPA sungguhan dengan routing dan controller tetap di Laravel. Alternatif Livewire untuk tim yang sudah nyaman dengan React atau Vue.inertiajs.comBaca rangkuman β
API-mu memakai Resource sehingga menambah kolom database tidak mengubah kontrak publik, daftar panjang memakai cursor, dan setiap panggilan HTTP keluar punya timeout.
Testing & Kualitas Kode
Tujuan: berani men-deploy pada Jumat sore β karena ada yang memeriksa selain matamu sendiri.
| Alat | Menangkap | Yang tidak bisa ditangkapnya |
|---|---|---|
| Tes fitur | Perilaku yang salah pada jalur yang diuji | Jalur yang tidak diuji |
| PHPStan | Tipe salah, null, method tak ada β di setiap baris | Aturan bisnis yang salah |
| Pint | Gaya kode | Segalanya yang lain |
| Uji arsitektur | Batas modul yang dilanggar | Kode yang jelek tapi patuh |
Yang wajib punya tes
- Setiap aturan otorisasi β dari sisi yang boleh dan yang tidak boleh.
- Setiap alur yang menyentuh uang atau data pribadi.
- Bentuk respons setiap endpoint API publik.
- Setiap bug yang pernah terjadi β tulis tesnya sebelum memperbaikinya.
- Jumlah query pada halaman daftar (
expectsDatabaseQueryCount).
Cakupan 100% tidak membuktikan apa pun. Yang lebih berguna: pastikan setiap aturan otorisasi dan setiap jalur uang punya tesnya sendiri. Itu daftar yang pendek, dan justru di situlah kegagalan paling mahal.
Materi
-
Dasar testing di LaravelResmiKenapa tes di Laravel murah ditulis, dan tes seperti apa yang benar-benar layak kamu punya.laravel.comBaca rangkuman β
-
PestResmiCara menulis tes yang lebih ringkas di atas PHPUnit. Sekarang jadi default starter kit Laravel.pestphp.comBaca rangkuman β
-
Tes HTTP & APIResmiMenguji rute, JSON, autentikasi, dan unggahan berkas tanpa server β termasuk memastikan bentuk respons API tidak berubah diam-diam.laravel.comBaca rangkuman β
-
Tes databaseResmiMenjaga tiap tes berangkat dari keadaan bersih β dan menjaga suite tetap cepat meski menyentuh database sungguhan.laravel.comBaca rangkuman β
-
Pint β gaya kodeResmiFormatter resmi Laravel. Satu perintah menghapus seluruh kategori komentar review yang tidak menambah nilai.laravel.comBaca rangkuman β
-
Larastan β analisis statisResmiMenemukan bug tanpa menjalankan kode. Level demi level, sampai typo dan null yang lolos tidak mungkin lagi.github.comBaca rangkuman β
Satu perintah composer periksa menjalankan Pint, PHPStan, dan seluruh tes β persis seperti
yang dijalankan CI. PHPStan berjalan di level 8 dengan baseline yang hanya menyusut.
Performa & Skala
Tujuan: tahu apa yang lambat berdasarkan data, dan memperbaikinya dengan urutan yang benar.
Urutan yang menghasilkan perbaikan terbesar per satuan risiko
- Perbaiki N+1 dan index. Dampaknya terbesar, risikonya nol.
- Cache HTTP dan CDN untuk halaman yang sama bagi semua orang.
php artisan optimizedan OPcache. Gratis.- Skala mendatar β tambah kontainer.
- Baru worker mode (Fase 8).
Banyak aplikasi yang mengira butuh worker mode sebenarnya butuh langkah kedua. Permintaan yang dijawab CDN tidak menyentuh PHP sama sekali β itu bukan perbaikan beberapa persen, itu penghapusan permintaannya. Dan tidak seperti worker mode, ia tidak menambah satu pun kelas bug baru.
Tiga tempat sebuah halaman bisa di-cache
| Lapisan | Menghemat | Dikendalikan |
|---|---|---|
| Browser | Seluruh perjalanan jaringan | max-age |
| CDN | Seluruh pemrosesan di servermu | s-maxage |
| Redis | Query dan render | Kodemu |
Peringatan yang tidak boleh dilewati: halaman yang isinya bergantung pada siapa yang login
harus private atau no-store. Satu halaman personal yang ditandai
public akan disimpan CDN dan disajikan ke orang lain β ini kebocoran data, bukan bug performa.
Anggaran yang layak dipegang
| Metrik | Target |
|---|---|
| Waktu respons server p50 / p95 | < 100 ms / < 400 ms |
| Query per permintaan | < 15, dan tidak bertambah seiring jumlah baris |
| Rasio hit CDN (situs konten) | > 90% |
| Rasio hit cache aplikasi | > 80% |
Materi
-
Optimasi deployResmiEnam perintah dan satu setelan PHP yang memangkas waktu respons sebelum kamu menyentuh satu baris kode pun.laravel.comBaca rangkuman β
-
Index databaseResmiSatu index yang tepat sering mengalahkan seluruh lapisan cache yang kamu tambahkan untuk menutupinya.dev.mysql.comBaca rangkuman β
-
RedisResmiSatu layanan yang menopang cache, session, antrean, dan penguncian β dan alasan kenapa ia jadi syarat begitu ada kontainer kedua.laravel.comBaca rangkuman β
-
HorizonResmiDasbor dan pengawas untuk antrean Redis β throughput, job gagal, dan penskalaan worker otomatis.laravel.comBaca rangkuman β
-
HTTP caching & CDNResmiLapisan cache yang paling murah adalah yang membuat permintaan tidak pernah sampai ke aplikasimu sama sekali.developer.mozilla.orgBaca rangkuman β
-
Pulse & TelescopeResmiMelihat apa yang sebenarnya lambat di aplikasimu β Pulse untuk produksi, Telescope untuk pengembangan.laravel.comBaca rangkuman β
Kamu bisa menunjuk rute paling lambat berdasarkan Pulse (bukan perasaan), sudah memperbaiki index yang
hilang berdasarkan EXPLAIN, dan halaman publikmu mengirim header s-maxage sementara
halaman personal mengirim no-store.
FrankenPHP & RoadRunner
Tujuan: paham persis apa yang dibeli worker mode, apa yang tidak, dan bisa memilih runtime berdasarkan bentuk beban kerjamu β bukan berdasarkan benchmark orang lain.
Yang sebenarnya berubah
| PHP-FPM | Worker mode | |
|---|---|---|
| Bootstrap framework | Tiap permintaan | Sekali per proses |
| Koneksi database | Dibuka ulang | Dipakai ulang |
| Variabel statis | Selalu bersih | Bertahan β bisa jadi bug |
| Kebocoran memori | Tidak mungkin bertahan | Menumpuk sampai restart |
| Deploy | Ganti berkas | Wajib restart proses |
Yang tidak diperbaiki worker mode: query N+1, index yang hilang, API luar yang lambat, halaman yang mengirim 2 MB HTML. Kalau permintaanmu 400 ms dengan 30 ms bootstrap dan 350 ms query, worker mode memberimu perbaikan 7% ditambah seluruh kelas bug state yang baru. Kerjakan Fase 7 dulu.
Perbandingan singkat
| Aspek | FrankenPHP | RoadRunner |
|---|---|---|
| Arsitektur | Satu proses: Caddy + PHP tertanam | Server Go + proses PHP terpisah |
| Konkurensi | Utas | Proses |
| Butuh PHP thread-safe | Ya | Tidak |
| Web server & TLS | Termasuk | Perlu di depannya |
| HTTP/3 | Bawaan | Ada di plugin http |
| Kendali pool | Utas, worker, kolam per rute | Sangat detail |
| Ekosistem | Modul Caddy | Jobs, gRPC, Temporal, KV |
| Alpine | Hindari (musl lambat untuk ZTS) | Hindari (musl tidak sepenuhnya kompatibel) |
Rekomendasi singkat β versi lengkapnya ada di materi terakhir fase ini. Untuk aplikasi web Laravel, mulai dari FrankenPHP: satu proses, satu konfigurasi, satu hal yang perlu dipantau. Pindah ke RoadRunner kalau ada kebutuhan konkret yang menariknya β gRPC, Temporal, antrean yang dikelola server, atau ekstensi PHP yang tidak thread-safe. Karena keduanya diakses lewat Octane, berpindah nanti berarti mengganti satu opsi, bukan menulis ulang aplikasi.
Daftar periksa sebelum menyalakan worker mode
- Tidak ada
singletonyang menyimpan data permintaan β ubah jadiscoped. - Tidak ada properti statis yang terus bertumbuh.
- Tidak ada
request()di dalam service provider. - Paket pihak ketiga sudah diperiksa dukungannya.
- Pemantauan memori per kontainer sudah terpasang.
- Pipeline deploy me-restart worker.
grep -rn "singleton(" app/ | grep -v scoped
grep -rn "static \$" app/
grep -rn "request()" app/Providers/
Materi
-
Model eksekusi PHP klasikResmiKenapa PHP membuang seluruh aplikasimu setiap permintaan β dan apa yang sebenarnya dibeli worker mode.www.php.netBaca rangkuman β
-
Laravel OctaneResmiSatu paket yang menjembatani Laravel ke FrankenPHP, RoadRunner, dan Swoole β dengan perintah yang sama untuk ketiganya.laravel.comBaca rangkuman β
-
Jebakan state di worker modeResmiKelas bug yang tidak ada di PHP-FPM: data satu pengguna bocor ke pengguna lain, dan memori yang naik terus.laravel.comBaca rangkuman β
-
FrankenPHP β pengantarResmiServer aplikasi PHP yang ditulis dalam Go, dengan PHP tertanam di dalamnya. Satu proses untuk TLS, HTTP/3, berkas statis, dan PHP.frankenphp.devBaca rangkuman β
-
FrankenPHP untuk LaravelResmiTiga cara menjalankan Laravel di atas FrankenPHP β Docker, biner lokal, dan Octane β beserta opsi yang perlu kamu setel.frankenphp.devBaca rangkuman β
-
FrankenPHP worker modeResmiCara kerja worker FrankenPHP dari dalam: loop permintaan, perilaku superglobal, dan state apa saja yang bertahan.frankenphp.devBaca rangkuman β
-
FrankenPHP di produksiResmiPenyetelan yang menentukan: glibc bukan musl, jumlah utas, GOMEMLIMIT, OPcache, dan cara mengurangi operasi filesystem.frankenphp.devBaca rangkuman β
-
RoadRunner β pengantarResmiServer aplikasi Go yang menjalankan proses PHP sebagai worker β plus ekosistem plugin: antrean, gRPC, KV, metrik.docs.roadrunner.devBaca rangkuman β
-
RoadRunner untuk LaravelResmiDua jalur integrasi: lewat Octane resmi, atau lewat Laravel Bridge yang membuka seluruh ekosistem plugin.docs.roadrunner.devBaca rangkuman β
-
Pool & supervisor RoadRunnerResmiKendali paling detail atas worker di antara semua runtime: batas memori, TTL, batas antrean, dan penskalaan dinamis.docs.roadrunner.devBaca rangkuman β
-
RoadRunner di produksiResmiDaftar saran resmi untuk produksi β state, memori, koneksi, dan satu peringatan tegas soal Alpine.docs.roadrunner.devBaca rangkuman β
-
FrankenPHP vs RoadRunner β mana untuk enterpriseArtikelPerbandingan menyeluruh dan rekomendasi yang tegas β beserta alasan kenapa jawabannya bergantung pada bentuk beban kerjamu.laravel.comBaca rangkuman β
Kamu punya tabel hasil uji beban sendiri untuk tiga konfigurasi β PHP-FPM, FrankenPHP klasik, dan
FrankenPHP worker mode β berisi throughput, p95, dan pemakaian memori. Dan kamu sudah membuktikan sendiri
kebocoran singleton lalu memperbaikinya.
Deploy di AWS
Tujuan: aplikasimu berjalan di AWS, di-deploy dari git push tanpa jeda, dengan
rahasia yang tidak pernah menyentuh repositori.
Arsitektur acuan
Route 53
β
CloudFront βββββββββββΊ S3 (aset & media)
β
WAF
β
Application Load Balancer (subnet publik)
β
ββββββββββββββ΄βββββββββββββ
β ECS Fargate β (subnet privat)
β βββββββββββββββββββββ β
β β service: web β β FrankenPHP + Laravel
β β service: worker β β queue:work
β β service: schedulerβ β schedule:work
β βββββββββββββββββββββ β
ββββββββββββββ¬βββββββββββββ
β
βββββββββββββββββΌβββββββββββββββββ¬βββββββββββββββ
Aurora ElastiCache SQS Secrets Manager
(writer + (Redis) + CloudWatch
reader)
Tiga service, bukan satu
| Service | Perintah | Task | Diskalakan dari |
|---|---|---|---|
web | octane:frankenphp | 2β20 | Permintaan per target |
worker | queue:work | 1β10 | Panjang antrean |
scheduler | schedule:work | Tepat 1 | β |
Empat setelan yang harus selaras supaya deploy benar-benar tanpa jeda: health check ALB,
deregistration_delay, stopTimeout ECS, dan penanganan SIGTERM. Aturannya:
stopTimeout harus lebih panjang daripada deregistration delay. Kalau salah satu tidak
sinkron, setiap rilis menghasilkan sejumlah 502 β dan biasanya tidak ada yang menyadarinya karena tidak ada
yang mengukurnya.
Urutan pipeline yang benar
- Lint dan analisis statis β paling cepat, gagalkan lebih dulu.
- Tes, dengan database sejenis produksi.
- Build image, tag dengan SHA commit β bukan
latest. - Pindai kerentanan image.
- Migrasi sebagai task tersendiri; periksa exit code-nya.
- Perbarui service β web, worker, dan penjadwal.
- Tunggu stabil, lalu jalankan pemeriksaan asap.
Materi
-
Memilih compute di AWSResmiEC2, Fargate, EKS, Lambda, Lightsail, App Runner β dan kenapa untuk Laravel jawabannya hampir selalu ECS Fargate.docs.aws.amazon.comBaca rangkuman β
-
Image produksi & ECRResmiDockerfile multi-stage yang menghasilkan image kecil, tanpa Node, tanpa dependensi dev, dan tidak berjalan sebagai root.frankenphp.devBaca rangkuman β
-
ECS FargateResmiMenjalankan kontainer tanpa mengelola satu pun server β cluster, service, dan task, plus tiga service yang dibutuhkan Laravel.docs.aws.amazon.comBaca rangkuman β
-
Task definition & konfigurasiResmiCetak biru kontainer: environment, rahasia, log, health check, dan stop timeout yang menyelamatkan job antrean.docs.aws.amazon.comBaca rangkuman β
-
Application Load BalancerResmiTLS, health check, dan penyebaran lalu lintas β plus setelan yang menentukan apakah deploy-mu benar-benar tanpa jeda.docs.aws.amazon.comBaca rangkuman β
-
Autoscaling ECSResmiMenambah task saat ramai dan menguranginya saat sepi β dengan metrik yang tepat untuk web dan untuk worker antrean.docs.aws.amazon.comBaca rangkuman β
-
Aurora & RDSResmiDatabase terkelola dengan writer dan reader terpisah β plus jebakan replication lag yang akan kamu temui.docs.aws.amazon.comBaca rangkuman β
-
ElastiCache untuk RedisResmiRedis terkelola yang memegang cache, session, dan lock β beserta keputusan cluster mode yang menentukan bentuk kodenya.docs.aws.amazon.comBaca rangkuman β
-
S3 & CloudFrontResmiMedia, aset, dan halaman yang di-cache di tepi jaringan. Untuk situs yang banyak dibaca, ini pengungkit terbesar yang kamu punya.docs.aws.amazon.comBaca rangkuman β
-
Secrets ManagerResmiMenyimpan
APP_KEY, kredensial database, dan token β tanpa satu pun rahasia di dalam image atau repositori.docs.aws.amazon.comBaca rangkuman β -
SQS & worker antreanResmiAntrean terkelola yang tidak kehilangan pekerjaan β beserta visibility timeout dan DLQ yang wajib kamu setel dengan benar.docs.aws.amazon.comBaca rangkuman β
-
CI/CD tanpa access keyResmiGitHub Actions yang mengambil peran AWS lewat OIDC β tanpa satu pun kredensial jangka panjang tersimpan di repositori.docs.aws.amazon.comBaca rangkuman β
-
Deploy tanpa jeda & observabilityResmiRolling update yang benar-benar mulus, circuit breaker yang mengembalikan versi lama, dan log yang bisa dibaca saat insiden.docs.aws.amazon.comBaca rangkuman β
git push ke main menghasilkan aplikasi baru di produksi tanpa satu pun respons
non-200 selama deploy, tanpa satu pun access key AWS tersimpan di GitHub, dan dengan rollback yang bisa
menunjuk revisi task definition sebelumnya.
Enterprise & Capstone
Tujuan: aplikasimu tetap bisa dipahami, diubah, dan di-upgrade setelah dua tahun dan lima orang yang berbeda menyentuhnya.
Fase-fase sebelumnya membuat aplikasi yang benar dan cepat. Fase ini tentang sifat yang baru terasa belakangan: apakah orang baru bisa menemukan kode yang dicarinya, apakah fitur bisa dimatikan tanpa deploy, dan apakah kamu masih bisa naik versi tahun depan.
Materi
-
Modularisasi kodeResmiMenjaga aplikasi besar tetap bisa dipahami β dan kenapa memecahnya jadi microservice biasanya bukan jawabannya.laravel.comBaca rangkuman β
-
Multi-tenancyArtikelSatu aplikasi melayani banyak pelanggan β tiga pola isolasi, dan satu kesalahan yang membocorkan data antar pelanggan.tenancyforlaravel.comBaca rangkuman β
-
Pencarian dengan ScoutResmiPencarian teks penuh yang tidak membebani database utama β dan kenapa
LIKE '%kata%'berhenti bekerja lebih cepat dari dugaanmu.laravel.comBaca rangkuman β -
Feature flag dengan PennantResmiMemisahkan "kode dirilis" dari "fitur dinyalakan" β supaya deploy berhenti terasa seperti taruhan.laravel.comBaca rangkuman β
-
Context β jejak lintas prosesResmiMembawa informasi seperti
request_iddantenant_idmenembus job antrean β supaya log bisa disatukan.laravel.comBaca rangkuman β -
Strategi upgrade & versiResmiRilis tahunan, dukungan dua tahun β dan cara menjadikan upgrade pekerjaan sehari, bukan proyek setahun.laravel.comBaca rangkuman β
Capstone: portal konten bertrafik baca tinggi
Bangun satu aplikasi yang menyentuh seluruh fase. Proyek yang paling tepat adalah yang didominasi pembaca anonim dengan sedikit penulis β karena bentuk beban itu memaksamu memakai hampir semua yang dipelajari di sini.
- Domain β artikel, kategori, penulis, komentar. Enum untuk status, objek nilai untuk hal yang punya aturan.
- Redaksi β alur draf β tinjau β terbit, dengan policy per peran dan tes dari kedua sisi.
- Media β unggahan ke S3, varian ukuran dibuat lewat antrean, disajikan lewat CloudFront.
- Halaman publik β Blade, tanpa JavaScript yang tidak perlu, dengan
s-maxagedanstale-while-revalidate. - Pencarian β Scout, dibatasi lajunya, hasilnya di-cache.
- API β Resource ber-versi, cursor pagination, Sanctum untuk konsumen.
- Kualitas β Pest, PHPStan level 8, Pint, uji arsitektur, semuanya jadi gerbang CI.
- Performa β index berdasarkan
EXPLAIN,preventLazyLoadingaktif, anggaran query di dalam tes. - Runtime β FrankenPHP worker mode, dengan daftar periksa state yang sudah dituntaskan.
- Infrastruktur β ECS Fargate tiga service, Aurora writer + reader, ElastiCache, SQS, Secrets Manager.
- Deploy β GitHub Actions lewat OIDC, migrasi sebagai task terpisah, nol respons non-200.
- Observability β log JSON dengan
request_id, delapan alarm, dasbor p95.
Kenapa proyek ini: ia memaksa setiap keputusan yang dibahas di roadmap. Beban baca tinggi menuntut strategi cache berlapis; alur redaksi menuntut otorisasi yang benar; media menuntut antrean dan penyimpanan objek; dan target tanpa jeda menuntut migrasi yang kompatibel dua arah. Kalau kamu bisa menjelaskan setiap keputusan di proyek ini, kamu bisa menjalankan aplikasi Laravel di produksi.
Aplikasi berjalan end-to-end di AWS, di-deploy dari pipeline, punya dasbor yang menunjukkan p95 dan rasio hit CDN, dan kamu bisa mematikan satu fitur tanpa deploy.
Rekomendasi best practice
Ringkasan keputusan yang, kalau harus memilih satu jawaban, inilah jawabannya. Konteksnya: aplikasi Laravel dengan lalu lintas baca yang jauh lebih besar daripada tulis β situs konten, katalog, portal. Setiap baris punya materi yang membahas alasannya.
Tumpukan yang direkomendasikan
| Lapisan | Pilihan | Alasan singkat |
|---|---|---|
| Framework | Laravel 13, PHP 8.4 | Dukungan keamanan sampai 2028 |
| Runtime | FrankenPHP + Octane | Satu proses; TLS, HTTP/3, dan berkas statis bawaan |
| Basis image | Debian, bukan Alpine | Kedua runtime worker mode menyarankan menghindari musl |
| Compute | ECS Fargate, tiga service | Tanpa server yang dikelola; proses berumur panjang |
| Database | Aurora MySQL, writer + reader | Beban baca dipindahkan ke replica |
| Cache & session | ElastiCache Redis, Multi-AZ | Wajib bersama begitu ada kontainer kedua |
| Antrean | SQS (+ Redis/Horizon kalau butuh dasbor) | Pekerjaan tidak hilang; tanpa klaster yang dikelola |
| Aset & media | S3 di belakang CloudFront | Bucket tidak pernah publik |
| Halaman publik | Blade, di-cache di CloudFront | Permintaan yang tidak pernah menyentuh PHP |
| Panel admin | Livewire | Interaktif tanpa membangun SPA |
| Rahasia | Secrets Manager lewat secrets ECS | Tidak ada rahasia di image maupun repositori |
| CI/CD | GitHub Actions + OIDC | Tanpa access key jangka panjang |
Sepuluh yang paling menentukan
- Pindahkan sebanyak mungkin ke CDN. Untuk halaman yang sama bagi semua pembaca,
s-maxageplusstale-while-revalidatememangkas beban server berkali-kali lipat β dan tidak menambah satu pun kelas bug. Ini pengungkit terbesar, dan yang paling sering dilewati. - Nyalakan
preventLazyLoading()sejak commit pertama. N+1 yang tidak pernah jadi error tidak akan pernah masuk daftar pekerjaan. - Buat index dari
EXPLAIN, bukan dari tebakan. Urutan kolom pada index gabungan menentukan apakah ia terpakai sama sekali. - Semua yang bersama harus di Redis β cache, session, lock β dengan database terpisah per
peran supaya
cache:cleartidak menghapus antrean. - Jangan lompat ke worker mode. Urutannya: N+1 dan index β CDN β
optimizedan OPcache β tambah kontainer β baru worker mode. - Sebelum worker mode, bereskan state. Tidak ada
singletonyang menyimpan data permintaan, tidak ada properti statis yang bertumbuh, tidak adarequest()di provider. - Job harus idempoten. Ia akan berjalan dua kali β SQS menjaminnya at-least-once, dan worker bisa mati setelah pekerjaan selesai tapi sebelum pesannya dihapus.
- Migrasi harus kompatibel dua arah. Selama rolling update, kode lama dan baru berjalan bersamaan. Ganti nama kolom = tiga deploy, bukan satu.
- Ukur p95, bukan rata-rata. Rata-rata menyembunyikan satu dari sepuluh pengguna yang menunggu tiga detik.
- Upgrade setiap tahun, bukan setiap empat tahun. Biaya upgrade tumbuh lebih cepat daripada linear terhadap waktu yang ditunda.
Kesalahan yang paling mahal
| Kesalahan | Akibatnya | Dibahas di |
|---|---|---|
Halaman personal ditandai public di CDN | Data satu pengguna tersaji ke pengguna lain | Fase 7, 9 |
singleton menyimpan data permintaan di worker mode | Kebocoran antar pengguna, hanya sesekali | Fase 3, 8 |
| Kunci cache tanpa ID tenant | Kebocoran antar pelanggan | Fase 3, 10 |
$guarded = [] | Kolom apa pun bisa diisi dari input pengguna | Fase 2 |
APP_DEBUG=true di produksi | Stack trace + seluruh environment terlihat publik | Fase 1 |
| Visibility timeout SQS lebih pendek dari durasi job | Job diproses berkali-kali; email dan tagihan dobel | Fase 9 |
Session driver file di banyak kontainer | Pengguna ter-logout acak | Fase 4, 7 |
Image tag latest | Rollback tidak mengembalikan apa pun | Fase 9 |
| Migrasi di entrypoint kontainer web | Lima task menjalankannya bersamaan saat scale-out | Fase 9 |
| Health check menyentuh database | Gangguan sebagian berubah jadi kegagalan total | Fase 9 |
Kalau lalu lintas naik, periksa dalam urutan ini
- Rasio hit CDN. Di bawah 90% untuk situs konten berarti ada yang salah di kunci cache β biasanya query string pelacakan atau cookie yang ikut masuk kunci.
- Query per permintaan. Kalau bertambah seiring jumlah baris, itu N+1.
- p95 database. Buka Performance Insights; query teratas biasanya menunjuk index yang hilang.
- Utas atau worker yang sibuk. Kalau selalu mentok, tambah task β bukan tambah worker per task.
- Panjang antrean. Menumpuk berarti worker kurang, atau ada job yang menahan.
- Baru pikirkan arsitektur. Lima langkah di atas menyelesaikan sebagian besar kasus.
Satu hal yang tidak akan diselesaikan infrastruktur: halaman yang butuh empat puluh query dan mengirim dua megabita HTML tetap mahal di runtime mana pun, di kelas instans apa pun. Ukur dulu, baru belanja.
Aturan main
- Bangun, jangan cuma baca. Hampir semua materi di sini punya latihan konkret di akhirnya; latihan itu yang membuatnya melekat.
- Ukur sebelum dan sesudah. Setiap klaim performa di roadmap ini bisa kamu buktikan sendiri dalam sepuluh menit β lakukan.
- Satu perubahan pada satu waktu. Mengubah runtime dan konfigurasi database bersamaan membuat hasilnya tidak bisa dibaca.
- Baca pesan error sampai habis. Bedakan masalah izin, masalah konfigurasi, dan masalah kode β ketiganya sering terlihat mirip.
- Jangan lompat ke Fase 8. Godaannya besar. Worker mode di atas kode yang belum bersih hanya menambah kelas bug baru.
- Hapus resource AWS setelah berlatih. Aurora, ElastiCache, dan NAT Gateway ditagih per jam, dipakai atau tidak.
- Tulis tes untuk setiap bug. Sebelum memperbaikinya, bukan sesudah.
Sebelum ini
Roadmap ini mengandaikan kamu sudah pernah menulis kode di bahasa apa pun dan paham dasar HTTP. Kalau belum pernah ngoding sama sekali, mulai dari Python Dasar untuk Pemula. Kalau kamu tertarik pada sisi infrastruktur AWS-nya secara lebih dalam, AWS untuk AI Engineer membahas IAM, IaC, dan observability dengan sudut pandang yang berbeda.