Mengenali struktur storage Laravel yang krusial untuk shared filesystem: membedakan folder yang harus di-share (storage dan public) dengan kode yang baked ke image, serta cara Laravel menulis dan membaca file lewat Storage facade

Sejak episode 0 kita membangun infrastruktur: NFS server, driver CSI, StorageClass, dan PVC. Sekarang mari melihat dari sisi yang sebaliknya — aplikasi. Kasus utama series ini adalah aplikasi web Laravel (misal portal upload foto/gallery) yang butuh shared storage untuk file-nya.
Mengapa episode ini penting? Keputusan terpenting dalam arsitektur storage bukan terletak di Kubernetes, melainkan di pemahaman aplikasi: folder mana yang boleh menjadi volume, mana yang harus menempel di image. Salah menentukan, dan kalian akan menghadapi perilaku aneh seperti session hilang atau upload ganda.
Kita membangun portal galeri foto. User upload foto, admin melihat thumbnail, dan semua itu bisa diakses publik. Aplikasi kita: Laravel 11/12 dengan filesystem local dan public, PHP 8.3-FPM, Nginx, PostgreSQL (opsional), dan Redis (untuk session/cache di episode 19).
Laravel menyimpan data runtime di storage/. Folder yang relevan dengan shared filesystem:
| Folder | Isi | Sifat |
|---|---|---|
storage/app/uploads | File asli upload (private) | Persisten, shared |
storage/app/public | File publik (symlink ke public/storage) | Persisten, shared |
storage/framework/sessions | Session file-based | Shared (atau pindah ke Redis) |
storage/framework/cache | Cache file-based | Shared (atau pindah ke Redis) |
storage/framework/views | Compiled blade | Shared (atau dibangun ulang) |
storage/logs | Log aplikasi | Shared |
Konfigurasi filesystem di .env:
FILESYSTEM_DISK=local
# atau FILESYSTEM_DISK=publicDisk local menyimpan di storage/app/private (default Laravel), disk public di storage/app/public. Kedua-duanya harus berada di volume bersama.
Ini keputusan arsitektur paling penting. Bagi aplikasi kita:
Yang di-share (menjadi PVC RWX):
storage/ — seluruh direktori, karena berisi upload, session, cache, log.Yang baked ke image (BUKAN volume):
vendor/ — dependency composer, dibangun saat build..env — konfigurasi, disuntikkan via ConfigMap/Secret (episode 23).public/ selain storage/ symlink — asset statis dari repo.Important
Regulasi praktis: apa pun yang ditulis saat runtime dan harus bertahan antar-replica → volume; apa pun yang bisa dibangun ulang saat di-deploy → image. Dengan aturan ini, image tetap kecil dan perilaku data terpusat.
Di kode aplikasi, Laravel memakai Storage facade. Contoh endpoint upload sederhana:
use Illuminate\Support\Facades\Storage;
public function upload(Request $request)
{
$path = $request->file('photo')->store('uploads', 'public');
return back()->with('ok', Storage::url($path));
}Operasi yang akan sering dipakai:
Storage::exists('uploads/foo.jpg'); // cek ada
Storage::put('uploads/bar.jpg', $content); // tulis
Storage::url('uploads/bar.jpg'); // URL publik
Storage::disk('public')->put('thumbnail/bar.jpg', $thumb); // tulis disk tertentu
Storage::delete('uploads/bar.jpg'); // hapusSemua operasi ini menulis ke storage/app/public — yang pada Pod kita bermuara ke volume RWX yang sama. Selama semua replica memakai path mount yang sama, file yang ditulis Pod A langsung terlihat di Pod B.
Tip
Simulasikan sekarang: tulis file Storage::put('uploads/probe.txt', 'hello') dan cek hasilnya di pod kedua dengan kubectl exec. Ini latihan paling cepat untuk merasakan manfaat RWX — kita lakukan versi lengkapnya di episode 10.
Pada episode 7 ini, kalian telah memetakan aplikasi ke storage:
Inti yang harus dibawa pulang:
storage/.storage/ dan symlink public/storage.vendor/, .env, kode aplikasi.Storage::put, Storage::disk, membaca via Storage::exists/Storage::url.Di episode 8 selanjutnya kita akan membangun Dockerfile Laravel production: multi-stage dengan composer, PHP-FPM, dan Nginx, entrypoint dan permission yang konsisten, serta optimasi ukuran image. Sampai jumpa di episode 8!