Skip to content

Fix: Perbaiki permission direktori upload storage/app/public menjadi 0755 - #1714

Merged
analisopendesa merged 3 commits into
rilis-devfrom
1713-storage-permission
Aug 26, 2026
Merged

Fix: Perbaiki permission direktori upload storage/app/public menjadi 0755#1714
analisopendesa merged 3 commits into
rilis-devfrom
1713-storage-permission

Conversation

@habibie11

Copy link
Copy Markdown
Contributor

issue # #1713

🎯 Deskripsi

Pull request ini memperbaiki masalah di mana file yang diunggah ke storage/app/public (seperti pada modul Form Dokumen, Album, Widget, dan aset publik lainnya) tidak dapat diakses di sisi publik dan menghasilkan error HTTP 404, meskipun file fisiknya ada di server.

Penyebab Masalah:

  1. Default Flysystem v3: Flysystem v3 (league/flysystem ^3.x) pada Laravel 10+ menggunakan PortableVisibilityConverter dengan nilai default directoryPrivate = 0700 dan defaultForDirectories = PRIVATE.
  2. Tanpa directory_visibility: Pada konfigurasi config/filesystems.php, disk local dan public tidak mengatur opsi directory_visibility. Parameter 'visibility' => 'public' pada disk public hanya berlaku untuk file, bukan direktori. Akibatnya, saat upload membuat subdirektori baru, direktori tersebut dibuat dengan izin (permission) 0700.
  3. Dampak di Multi-Tenant / suEXEC: Pada arsitektur multi-tenant (seperti OpenLiteSpeed suEXEC atau Nginx + PHP-FPM dengan beda user), file PHP berjalan di bawah user desa/site (misal: sid_<id>), sedangkan file statis (public/storage) dilayani langsung oleh web server sebagai user nobody. Karena direktori berizin 0700, web server tidak dapat melakukan directory traversal sehingga merespon dengan HTTP 404.

Solusi yang Diterapkan:

  1. Menambahkan 'directory_visibility' => 'public' pada disk local dan public di config/filesystems.php. Ini memastikan semua pembuatan direktori baru via Flysystem otomatis berizin 0755.
  2. Membuat Artisan Command storage:fix-permissions (app/Console/Commands/FixStoragePermissions.php) untuk memeriksa dan mengubah direktori lama di storage/app/public yang berizin < 0755 menjadi 0755. Dilengkapi opsi --dry-run dan deteksi OS (otomatis lewati jika di lingkungan Windows).
  3. Membuat Database Migration (database/migrations/2026_08_26_000001_fix_storage_directory_permissions.php) yang otomatis memicu storage:fix-permissions saat proses upgrade (php artisan migrate), sehingga instalasi yang sudah berjalan langsung terperbaiki secara otomatis tanpa perlu intervensi manual.

🛠️ Perubahan yang Dilakukan

1. config/filesystems.php

Fix — Penambahan directory_visibility pada disk local dan public:

  • Menambahkan konfigurasi 'directory_visibility' => 'public' agar direktori yang baru dibuat oleh Flysystem v3 memiliki permission 0755 (bukan default 0700).
         'local' => [
             'driver' => 'local',
-            'root' => storage_path('app'),
-            'throw' => false,
+            'root'   => storage_path('app'),
+            'throw'  => false,
+            // Fix #1713: Flysystem v3 default directoryPrivate = 0700.
+            // Pada setup multi-tenant (OLS/Nginx + PHP-FPM), direktori 0700
+            // tidak dapat di-traverse oleh user web server (misal: nobody) → 404.
+            'directory_visibility' => 'public',
         ],
 
         'public' => [
-            'driver' => 'local',
-            'root' => storage_path('app/public'),
-            'url' => env('APP_URL').'/storage',
-            'visibility' => 'public',
-            'throw' => false,
+            'driver'     => 'local',
+            'root'       => storage_path('app/public'),
+            'url'        => env('APP_URL').'/storage',
+            'visibility' => 'public',
+            // Fix #1713: visibility hanya berlaku untuk file, bukan direktori.
+            // directory_visibility memastikan direktori baru dibuat 0755 (bukan 0700).
+            'directory_visibility' => 'public',
+            'throw'      => false,
         ],

2. app/Console/Commands/FixStoragePermissions.php

Feature — Artisan Command storage:fix-permissions:

  • Membuat command baru untuk menelusuri seluruh direktori di storage/app/public secara rekursif.
  • Mengubah permission direktori yang < 0755 menjadi 0755.
  • Menyediakan opsi --dry-run untuk melihat pratinjau direktori yang perlu diperbaiki tanpa langsung mengubah file system.
  • Melewati eksekusi jika dijalankan di sistem operasi Windows.

3. database/migrations/2026_08_26_000001_fix_storage_directory_permissions.php

Feature — Migrasi otomatis perbaikan permission storage:

  • Menjalankan perintah storage:fix-permissions secara otomatis saat php artisan migrate dieksekusi selama proses pembaruan/rilis aplikasi.
  • Metode down() sengaja dibiarkan no-op untuk mencegah pengembalian direktori ke izin 0700 yang berisiko memicu kembali error 404.

✅ Test Cases yang Diimplementasikan

  • Konfigurasi config/filesystems.php memuat 'directory_visibility' => 'public' untuk disk local dan public.
  • Command php artisan storage:fix-permissions dapat dijalankan dengan opsi --dry-run maupun eksekusi langsung.
  • Migrasi 2026_08_26_000001_fix_storage_directory_permissions.php berhasil memanggil command perbaikan storage saat up().
  • Seluruh file PHP yang dibuat/diubah lolos validasi sintaks (php -l).

📸 Cara Menjalankan Uji Coba Manual

  1. Di server Linux / lingkungan multi-tenant (OpenLiteSpeed / Nginx):
    # Jalankan migrasi untuk memperbaiki direktori storage yang sudah ada
    php artisan migrate
  2. Cek permission folder di dalam storage/app/public/:
    stat -c "%a %n" storage/app/public/*
    # Pastikan semua direktori berizin 755 (drwxr-xr-x)
  3. Lakukan upload file baru melalui modul (contoh: Form Dokumen, Album, atau Widget).
  4. Pastikan subdirektori baru yang dibuat otomatis berizin 755 dan file dapat diakses langsung via URL browser/curl:
    curl -I http://domain-opendk.test/storage/form_dokumen/nama-file.pdf
    # Pastikan mengembalikan HTTP/1.1 200 OK

🤖 Cara Menjalankan Uji Coba Otomatis (Automated Test)

Untuk menguji sintaks dan menjalankan perintah perbaikan storage melalui artisan:

# Validasi sintaks file
php -l config/filesystems.php
php -l app/Console/Commands/FixStoragePermissions.php
php -l database/migrations/2026_08_26_000001_fix_storage_directory_permissions.php

# Pratinjau perbaikan direktori storage (dry-run)
php artisan storage:fix-permissions --dry-run

📸 Screenshot atau Video

[isi foto atau video jika ada]


⚠️ Catatan Penting

Perubahan directory_visibility => 'public' di config/filesystems.php mencakup seluruh operasi penyimpanan Flysystem (local dan public), sehingga upload baru secara otomatis membuat direktori dengan izin 0755. Migrasi otomatis memastikan instalasi multisite yang sudah ada sebelumnya langsung diperbaiki saat pembaruan rilis.

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI PR Review sedang antri di server...

Proses review akan segera dimulai di background — hasil akan muncul sebagai komentar setelah selesai.
Powered by CrewAI · PR #1714

@ujgsp

ujgsp commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Ujicoba/test opendk di server terkait direktori 404 (selesai dan berfungsi)

deskripsi tiket: terkait issue #1713 Pull Request sudah tersedia dan perlu dipastikan di test di server OpenDK link tiket: https://opslog.opendesa.id/tickets/2684

uji coba di demodk

direplikasi bareng mas Habibi dan mba Firli
note: before: terlihat masih menggunakan branch/tag rilis dan ada folder yang 700

root@xxxx:/var/www/html/demodk/public_html# git branch -vv
* (HEAD detached at v2608.0.2) 93aee21a Rilis v2608.0.2 (#1712)
  master                       9c9f534b [origin/master: behind 297] Merge Pull Request From🛡️ Batch Dependabot Security Updates - 2026-06-09 (#1579)
root@server-demo:/var/www/html/demodk/public_html# stat -c "%a %n" storage/app/public/*
755 storage/app/public/artikel
755 storage/app/public/backup-temp
755 storage/app/public/files
755 storage/app/public/form_dokumen
755 storage/app/public/framework
700 storage/app/public/kecamatan
755 storage/app/public/media_terkait
700 storage/app/public/medsos
755 storage/app/public/penduduk
700 storage/app/public/pengurus
755 storage/app/public/photos
755 storage/app/public/potensi_kecamatan
755 storage/app/public/profil
755 storage/app/public/publikasi
755 storage/app/public/regulasi
700 storage/app/public/sinergi
755 storage/app/public/slide
755 storage/app/public/temp
755 storage/app/public/template_upload
755 storage/app/public/user
755 storage/app/public/widget
root@server-demo:/var/www/html/demodk/public_html#

after menggunakan pr mas habibi, terlihat folder sudah 755 jalankan perintah ini dulu:

php artisan migrate (untuk trigger command console: php artisan storage:fix-permissions)
root@xxx:/var/www/html/demodk/public_html# stat -c "%a %n" storage/app/public/*
755 storage/app/public/artikel
755 storage/app/public/backup-temp
755 storage/app/public/files
755 storage/app/public/form_dokumen
755 storage/app/public/framework
755 storage/app/public/kecamatan
755 storage/app/public/media_terkait
755 storage/app/public/medsos
755 storage/app/public/penduduk
755 storage/app/public/pengurus
755 storage/app/public/photos
755 storage/app/public/potensi_kecamatan
755 storage/app/public/profil
755 storage/app/public/publikasi
755 storage/app/public/regulasi
755 storage/app/public/sinergi
755 storage/app/public/slide
755 storage/app/public/temp
755 storage/app/public/template_upload
755 storage/app/public/user
755 storage/app/public/widget
root@server-demo:/var/www/html/demodk/public_html# 

note: test di menu medsos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants