رفع خطای مرسوم Permission denied ".../storage/logs/laravel.log could not be opened" در لاراول

من زیاد لاراول بلد نیستم و کاملن مبتدی هستم اما چون خودم با این خطا روبرو شدم و یه کم طول کشید که بفهمم چه جوری باید درستش کنم، چیزی رو که نهایتن پیدا کردم این جا می نویسم تا شاید به درد کسی بخوره. اصل داستان رو از این جا ترجمه کردم اما از این جا هم کمک گرفتم.اگه دستورهای لینوکسی رو خوب بلدید، بهتره یه راست برید سراغ بخش آخر این نوشته. وگرنه با ما همراه باشید. :)راه کوتاهکل قضیه اینه که باید دسترسی نوشتن روی دو تا پوشه ی storage و bootstrap/cache رو به وب سرور بدید. مسئله ای که در مستندات لاراول ذکر شده (فرید عقیلی این مسئله رو متذکر شد).قصه چیه؟بعضی وقتا (مثلن وقتی می خواید از طریق وب، توی پروژه ی لاراولی تون امکان آپلود فایل بذارید) با چنین خطایی روبرو می شید:Permission denied &quot.../storage/logs/laravel.log could not be opened&quotنمونه خطای منع دسترسی به لاگ لاراولخطا می گه: من می خوام توی این فایلی که گفتیم (لاگ لاراول) یه چیزی بنویسم اما بهش دسترسی ندارم و نمی تونم. چرا؟ باید یه چیزایی رو قبلش بدونیم.دسترسی های یونیکسیبه فایل ها و پوشه ها توی ساختار یونیکسی (که شامل همه ی توزیع های لینوکس می شه) سه نوع دسترسی می شه داشت:خواندن (read)نوشتن (write): تغییر فایل بدون اجراش.اجرا (execute)همچنین فایل ها و پوشه ها به مالک (owner) و گروه (group) متصل می شن. مالک یعنی کسی که اون فایل یا پوشه رو ساخته (یا فرض می گیریم که ساخته) و قاعدتن اختیار تغییر یا حتا پاک کردن فایل رو داره. مالک یک نفره. یک نام کاربری. گروه یعنی گروهی از نام های کاربری (افراد) که می تونیم بگیم به یه فایل یا پوشه چه نوع دسترسی هایی دارند. وقتی مثلن می گیم گروه root به یه فایل دسترسی نوشتن دارند، یعنی هرکسی که توی این گروهه این دسترسی رو داره.اجازه ی خواندنبا یه دستور ساده توی ترمینال لینوکس می شه دسترسی هایی رو که به هر فایل و پوشه وجود داره دید (توی این دستور ls مخفف list است. این دستور، یه دستور پایه ای توی همه ی توزیع های لینوکسی است که باهاش می شه فهرست فایل ها و پوشه ها رو در هر جایی که هستیم، دید. بقیه ی دستور، یه سری فلگه. فلگ -a (مخفف --all) یعنی همه ی فایل ها و پوشه ها رو نشون بده حتا اونایی که با نقطه شروع می شن، فلگ l (مخفف long) یعنی فرمت مفصل فهرست رو نشون بده و فلگ h (مخفف --human-readable) یعنی یه جور آدم‌فهم فهرست کن که راحت بشه فهمید!):ls -alhکه مثلن یه همچین چیزی به عنوان خروجی نشونتون می ده:drwxrwxr-x 5 amir amir 4.0K May 28 13:58 . drwxrwxr-x 18 amir amir 4.0K Jun 9 10:38 .. -rw-r--r-- 1 amir amir 5.6K Dec 10 18:19 book_default_cover.png -rw-rwxr-- 1 www-data amir 11K Oct 26 2016 favicon.ico drwxr-xr-x 3 root root 4.0K Jun 9 2019 opt dr-xr-xr-x 137 root root 0 Jan 28 06:33 proc drwx------ 8 root root 4.0K Jan 31 15:07 root drwxr-xr-x 37 root root 1.4K May 2 03:50 run drwxr-xr-x 2 root root 12K Feb 8 07:04 sbin drwxr-xr-x 2 root root 4.0K May 24 2019 snap drwxr-xr-x 3 root root 4.0K May 25 2019 srv dr-xr-xr-x 13 root root 0 Jan 28 06:33 sysهر خط هفت تا ستون داره. آخرین ستون که اسم فایل یا پوشه است. حالا بریم سراغ اولین ستون. اولین حرف ستون اول در هر خط می گه اون خط مربوط به یه پوشه است (d به معنی directory) یا فایل (- به نشانه ی فایل بودن). بعدش سه سری rwx وجود داره:اولین rwx مربوط به سطوح دسترسی مالک (onwer)ه.دومین rwx مربوط به سطوح دسترسی گروه (group)ه.سومین rwx مربوط به سطوح دسترسی بقیه (other) است.خب تقریبن مشخصه که r مخفف read (سطح دسترسی خواندن)، w مخفف write (سطح دسترسی نوشتن) و x مخفف execute (سطح دسترسی اجرا) است. اگه یه جا علامت - (hyphen) وجود داشته باشه یعنی اون فرد، اون سطح دسترسی رو برای اون خط نداره. مثلن پوشه ی run رو ببینید که گروه و بقیه سطح دسترسی w رو بهش ندارند. یه نکته ی مهم این که برای این که بتونیم وارد یه پوشه بشیم باید سطح دسترسی اجرا داشته باشیم.ستون سوم می گه مالک اون فایل یا پوشه کیه. مثلن این جا مالک book_default_cover.png نام کاربری amirه اما مالک snap نام کاربری rootه. ستون چهارم می گه این فایل یا پوشه به چه گروهی متصله. مثلن توی مثالی که زدیم گروه book_default_cover.png باز هم اسمش amirه و گروه snap هم باز اسمش rootه. اما مثلن در مورد favicon.ico: مالک این فایل www-data است اما گروهش amirه.فرمت هشت هشتیسطح دسترسی به شکل هشت هشتی (اکتال: octal) هم قابل نمایشه. توی این فرمت، هر سطح دسترسی یه عدد داره:خواندن: 4نوشتن: 2اجرا: 1عدم دسترسی: 0این عددها با هم جمع می شن و سطح دسترسی رو مشخص می کنند. مثلن عدد 7 (جمع 4 و 2 و 1) دسترسی کامل رو نشون می ده. دسترسی خواندن و اجرا (بدون دسترسی نوشتن) عدد 5ه (جمع 4 و 1). حالا اگه سه تا عدد توی این فرمت رو نشون بدیم، می شه همون سه تا سری rwx (که اولیش مربوط به مالک، دومیش مربوط به گروه و سومیش مربوط به بقیه بود). مثلن 777 یعنی هم مالک، هم گروه و هم بقیه دسترسی کامل به اون فایل یا پوشه دارند. یا توی همون مثال بالا سطح دسترسی favicon.ico این بود: rw-rwxr--که می شه: 674 (دسترسی مالک خواندن و نوشتنه که می شه 4+2 = 6، دسترسی گروه همه چیزه که می شه: 4+2+1 = 7 و دسترسی بقیه فقط خواندنه که می شه 4).تنظیم دسترسیدو تا دستور برای کنترل سطوح دسترسی وجود داره:اولیش: chmod که مخفف change mode (تغییر حالت)ه که برای تغییر سطح دسترسی استفاده می شه.دومیش: chown که مخفف change ownership (تغییر مالکیت)ه که برای تغییر مالک و گروه استفاده می شه.این دو تا دستور یه فلگ -R هم دارند که یعنی به شکل برگشتی (recursive) دستور رو اجرا کن. یعنی چی؟ یعنی اگه دستور رو روی یه پوشه اجرا کردید، نه تنها روی اون پوشه تغییر بده که روی هر چی فایل و پوشه که توی اون پوشه است هم این تغییر رو اعمال کن.حالا چطوری اون خطا رو برطرف کنیم؟گفتیم که این خطا معمولن وقتی پیش میاد که می خواید امکان آپلود فایل رو توی سایت لاراولی خودتون فعال کنید اما خیلی جاهای دیگه هم ممکنه پیش بیاد. مثلن هر وقت که لاراول می خواد یه چیزی رو توی لاگش بنویسه و بعد می بینه دسترسی نداره. فرض کنیم نام کاربری لینوکسی ما در این پروژه amirه. و اگه در اوبونتو از وب سرور آپاچی یا وب سرور nginx استفاده می کنید، اسم مالک و گروه پیش فرض این دو تا هم www-data است. حالا باید چی کار کنیم؟ باید یه سری تغییرات روی پوشه ی storage (که مسبب این خطا بوده) اعمال کنیم. اول باید مالک پوشه ی storage رو بذاریم همون amir و گروهش رو هم بذاریم وب سرور (که این جا www-data است). بعدش هم سطح دسترسی این پوشه رو برای مالک و گروه به شکل کامل فعال کنیم و برای بقیه هم امکان خواندن و اجرا رو فعال کنیم اما امکان نوشتن رو غیرفعال کنیم. پس می ریم به پوشه ی پروژه ی لاراولی مون و این دو تا دستور رو اجرا می کنیم:chown -R amir:www-data ./storage chmod -R 775 ./storageخب تموم شد. دیگه اون خطا نمایش داده نمی شه.نکته: ممکنه برای پوشه ی bootstrap/cache هم این خطا پیش بیاد. روش برطرف کردن این هم، همون شکلیه:chown -R amir:www-data ./bootstrap/cache chmod -R 775 ./bootstrap/cache