Hamizulfaiz

Tech Entrepreneur / System Builder

Bila Deploy Laravel, Permission Bukan Masalah Kecil

Published:

Updated:

Sistem Laravel

Ada satu benda yang agak annoying bila maintain Laravel application dekat VPS.

First deployment okay.

Everything works.

Laravel boleh write log.

Upload file boleh.

Storage boleh.

Cache boleh.

Then aku deploy perubahan baru.

Tiba-tiba:

Cannot append log. Permission denied

Laravel tak boleh write log.

File upload gagal.

Private file tak boleh disimpan.

Kadang-kadang benda yang sama berlaku dekat bootstrap/cache.

Lepas tu aku masuk server.

Check permission.

Betulkan.

Problem hilang.

Sampai next deployment.

Then repeat.

Pada awalnya aku anggap ini sebagai:

"Laravel storage permission problem."

Tapi lama-lama aku rasa framing tu salah.

Sebab kalau benda yang sama boleh berlaku tak kira aku deploy menggunakan Git bare, GitHub Actions, self-hosted runner, Docker atau platform macam Coolify, maksudnya deployment mechanism tu bukan root cause sebenar.

Ada benda yang lebih fundamental.


Sebenarnya ada dua process yang bekerja pada application yang sama

Bila kita cakap pasal Laravel application, kita selalu fikir:

Laravel

Tapi dekat server, Laravel bukan satu process.

Ada process yang deploy application.

Ada process yang run application.

Contohnya deployment mungkin dibuat oleh:

git bare
GitHub Actions
self-hosted runner
Docker
Coolify
SSH
 

Manakala application pula mungkin berjalan melalui:

Nginx
PHP-FPM
queue worker
scheduler
 

Dan process-process ni boleh menggunakan user atau group yang berbeza.

Contohnya:

deployment
    ↓
deploy user

runtime
    ↓
www-data
 

Sekarang bayangkan deployment create satu directory baru:

storage/something

Kalau directory tu dimiliki oleh deployment user dengan permission tertentu, kemudian PHP-FPM cuba write dekat situ sebagai www-data, Linux akan check:

User ni boleh write ke sini tak?

Kalau tak boleh:

Permission denied

Laravel cuma menjadi tempat error itu muncul.


Jadi aku mula tukar cara aku tengok deployment

Aku tak lagi fikir:

"Macam mana nak fix Laravel permission?"

Aku lebih suka tanya:

"Siapa yang akan create file ini, dan siapa yang akan gunakan file ini?"

Nampak macam soalan simple.

Tapi soalan ni sebenarnya membawa kita kepada banyak benda lain.

Siapa deploy?

Siapa run PHP?

Siapa run queue?

Siapa create uploaded file?

Siapa create log?

Siapa create cache?

Siapa perlu read?

Siapa perlu write?

Group apa yang mereka share?

Apa permission yang inherited bila file baru dicipta?

Bila mula tanya soalan macam ni, filesystem permission tak lagi nampak macam benda kecil.

Ia dah jadi sebahagian daripada architecture.


chmod 777 memang boleh "solve"

Dan inilah perangkap paling senang.

Bila Laravel tak boleh write:

chmod -R 777 storage

Problem hilang.

Of course.

Sebab kita basically cakap:

"Semua orang boleh buat apa saja."

😂

Tapi bagi aku, itu bukan solution.

Ia cuma menghilangkan constraint yang menyebabkan error.

Kita sebenarnya belum jawab:

Siapa yang sepatutnya boleh write?

Dan itu soalan yang lebih penting.


Aku lebih suka ada ownership model yang jelas

Contohnya, untuk satu Laravel application, aku boleh decide:

deployment user
    deploy

runtime user
    www-data

Kemudian aku boleh tentukan bahawa writable directory Laravel menggunakan shared group.

Contohnya:

storage/
    deploy:www-data

bootstrap/cache/
    deploy:www-data
 

Sekarang deployment process dan PHP-FPM mempunyai relationship yang jelas.

Bukan sekadar:

"chmod sampai tak error"

Tetapi:

deployment
    ↓
deploy:www-data
    ↓
shared writable directories
    ↓
PHP-FPM

Itu lebih predictable.


Di sinilah aku jumpa setgid

Satu detail Linux yang sebenarnya sangat sesuai untuk scenario macam ni ialah setgid pada directory.

Contohnya:

2775

Kebanyakan kita biasa nampak:

775

Tapi 2 dekat depan tu penting.

Ia bermaksud directory tersebut menggunakan setgid.

Salah satu behavior pentingnya ialah file atau directory yang dicipta di bawahnya akan inherit group daripada parent directory.

Contohnya:

storage/
    deploy:www-data
    2775

Bila sesuatu process create file baru dalam storage, group inheritance boleh kekal sebagai:

www-data

Jadi kita boleh bina satu filesystem model di mana deployment user dan runtime user boleh bekerja pada data yang sama tanpa setiap deployment merosakkan ownership yang diperlukan oleh runtime.

Bagi aku, ini bukan lagi sekadar:

"Oh, chmod 2775."

Ia sebenarnya:

Aku sedang define relationship antara deployment process dengan runtime process melalui filesystem.

Itu yang lebih menarik.


Tapi 2775 bukan bermaksud semua benda perlu writable

Ini pun penting.

Aku tak nak application code aku jadi writable secara membuta tuli.

Aku tak perlu:

app/
config/
routes/
resources/
vendor/

menjadi writable kepada runtime.

Laravel cuma perlukan tempat tertentu untuk write.

Biasanya:

storage/
bootstrap/cache/

Jadi permission model aku patut reflect requirement sebenar application.

Bukan:

everything writable

Tetapi:

code
    mostly read-only

runtime directories
    writable
 

Benda ni nampak kecil.

Tapi sebenarnya ini adalah principle of least privilege yang sama kita gunakan dalam security design.

Bagi permission hanya dekat tempat yang memerlukannya.


Lagi aku fikir, lagi aku rasa storage patut dipisahkan daripada deployment

Ini mungkin lebih penting daripada permission itu sendiri.

Application code boleh dibuang.

Kita boleh deploy version baru.

Kita boleh rollback.

Kita boleh rebuild container.

Kita boleh checkout commit lain.

Tetapi uploaded files?

Itu data.

Kalau user upload:

invoice.pdf
profile.jpg
medical-report.pdf
document.pdf

file-file tersebut tak sepatutnya bergantung kepada lifecycle application code.

Sebab itu aku suka architecture yang lebih kurang macam:

/var/www/myapp

├── releases/
│   ├── release-001/
│   ├── release-002/
│   └── release-003/
│
├── current
│
└── shared/
    └── storage/

Application release boleh berubah.

Tetapi:

shared/storage

kekal.

Jadi deployment tak perlu kacau persistent data setiap kali code berubah.


Ini juga explain kenapa deployment technology bukan penyelesaian

Kita boleh tukar deployment mechanism.

Contohnya:

Git bare

tak semestinya lebih baik daripada:

GitHub Actions

Dan GitHub Actions pula tak semestinya menghapuskan masalah berbanding:

Docker

Docker pula tak semestinya membuat filesystem permission menjadi irrelevant.

Malah Docker boleh memperkenalkan satu lagi dimension:

UID
GID
container user
host user
volume
bind mount
 

Kalau host create file dengan UID tertentu tetapi container run sebagai UID lain, kita masih boleh dapat:

Permission denied

Sebab akhirnya semua ni masih berinteraksi dengan satu benda:

Linux filesystem.

Deployment tool cuma menentukan bagaimana kita sampai ke filesystem tersebut.


Sebab itu aku suka fikir dalam bentuk "contract"

Daripada bergantung kepada:

"Setup server ni sekali dan harap tak rosak."

Aku lebih suka ada filesystem contract.

Contohnya:

Application
    owner/group → deploy:www-data

Runtime writable directories
    storage/
    bootstrap/cache/

Directory permission
    2775

File permission
    664

Persistent storage
    separate from release

Sekarang bila aku tukar deployment mechanism, aku cuma perlu pastikan mechanism tersebut memenuhi contract ini.

Tak kisah sama ada:

Git bare
GitHub Actions
Docker
Coolify
self-hosted runner

Implementation boleh berubah.

Contract kekal.


Ini sebenarnya pattern yang lebih besar

Benda ni mengingatkan aku bahawa banyak masalah production sebenarnya bukan masalah technology.

Kita selalu cuba solve berdasarkan tool:

"Laravel error."

"Docker problem."

"Nginx problem."

"Git deployment problem."

"Coolify problem."

Padahal kadang-kadang semua tu cuma symptom.

Masalah sebenar ialah kita tak define interaction antara components dengan cukup jelas.

Dalam kes ni:

Deployment
       ↓
Application files
       ↓
Runtime
       ↓
Persistent data

Siapa own apa?

Siapa boleh read?

Siapa boleh write?

Apa yang persistent?

Apa yang disposable?

Apa yang berlaku bila deployment baru replace files?

Apa yang berlaku bila application create file baru?

Bila soalan-soalan ni dijawab awal, banyak "random production issue" mula jadi predictable.


Jadi sekarang, bila aku setup Laravel dekat VPS...

Aku tak anggap permission sebagai benda yang akan aku fix nanti.

Aku anggap ia sebahagian daripada setup architecture.

Aku nak tahu:

Who deploys?
Who runs the application?
Who writes runtime data?
Which directories are writable?
Which data must survive deployment?
Which users/groups need access?
How does newly-created data inherit ownership?
 

Dan baru daripada situ aku decide:

ownership
groups
setgid
permissions
directory structure
deployment process

Bukan sebaliknya.

Bukan:

Error
 ↓
chmod
 ↓
Error hilang
 ↓
Done

Tetapi:

Requirements
 ↓
Ownership model
 ↓
Filesystem permissions
 ↓
Deployment architecture
 ↓
Predictable runtime
 

Bagi aku, itu beza antara "server setup" dengan "production architecture."

Sebab production yang baik bukan production yang tak pernah ada error.

Production yang baik ialah bila kita boleh explain kenapa system berkelakuan macam itu, dan bila deployment berubah, kita masih tahu apa yang patut berlaku.

Dan untuk sesuatu yang nampak kecil macam Laravel storage permission, sebenarnya ada banyak architecture decision yang duduk di belakangnya.

 

Laravel VPS: Permission Adalah Sebahagian Architecture

Nak buat sistem?

Jom bincang untuk develop sistem yang custom untuk anda.

nak buat sistem bisnes? hubungi saya

Post Berkaitan

14 Sep 2026 Aku Dah Outgrow Laravel Valet
Aku Dah Outgrow Laravel Valet

Bila projek makin complex, setup Valet mula tak cukup. Ini workflow aku bila native development mula bertembung dengan Docker.

07 Sep 2026 Sistem Bisnes Tak Pernah Betul-Betul Siap
Sistem Bisnes Tak Pernah Betul-Betul Siap

Kenapa sistem yang dah siap masih perlukan perubahan? Tentang realiti software, perubahan bisnes dan kenapa V1 bukan versi terakhir.

04 Sep 2026 Rembayung: Bila Sistem Booking Berdepan Traffic Tinggi dan Isu Scalping
Rembayung: Bila Sistem Booking Berdepan Traffic Tinggi dan Isu Scalping

Bila restoran jadi viral, sistem booking bukan sekadar soal server. Ini analisis tentang traffic, scalping dan cara reka bentuk flow yang lebih praktikal.

31 Aug 2026 Jangan Terus Bina Sistem. Faham Dulu Flow Yang Nak Diselesaikan
Jangan Terus Bina Sistem. Faham Dulu Flow Yang Nak Diselesaikan

Ramai terus bina sistem bila bisnes bermasalah. Tapi sebelum automate, faham dulu flow, bottleneck dan punca sebenar masalah.

20 Jul 2026 Penemuan Bukan Datang Sebab Pandai. Ia Bermula Dengan Pemerhatian
Penemuan Bukan Datang Sebab Pandai. Ia Bermula Dengan Pemerhatian

Bagaimana penemuan maltose mengajar kita bahawa pemerhatian lebih penting daripada sekadar ilmu dalam bisnes dan pembangunan perisian.

06 Jul 2026 Environment Dalam Pembangunan Software: Perspektif Bisnes vs Developer
Environment Dalam Pembangunan Software: Perspektif Bisnes vs Developer

Fahami perbezaan local, staging dan production serta bagaimana developer mengurus APP_ENV dan secrets dalam software.

29 Jun 2026 Perlu Ke Buat Sistem?
Perlu Ke Buat Sistem?

Perlu ke buat app atau software untuk bisnes? Ketahui bila anda perlukan sistem dan bila anda sebenarnya belum memerlukannya.

22 Jun 2026 5 Red Flags Developer Sistem Yang Buat Projek Gagal Sebelum Mula
5 Red Flags Developer Sistem Yang Buat Projek Gagal Sebelum Mula

Nak buat sistem custom? Elak 5 red flags developer ini sebelum projek lambat, kos mengelembung, dan sistem gagal digunakan.

10 Jun 2026 Di Sebalik Tabir: Bagaimana Aku Setup Ekosistem Software Yang Laju, Selamat & Automatik
Di Sebalik Tabir: Bagaimana Aku Setup Ekosistem Software Yang Laju, Selamat & Automatik

Ketahui cara setup sistem perniagaan, booking homestay, dan AI WhatsApp closer menggunakan dedicated isolated VPS untuk kelajuan dan keselamatan data perniagaan anda.

HAMIZULFAIZ