CentOS + Laravel error: Permission denied in /vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107

laravel

Trong quá trình cài đặt Laravel trên môi trường CentOS 7, tôi đã gặp phải vấn đề về permission denied cho file laravel.log và folder /bootstrap/cache. Cụ thể là đoạn lỗi dưới đây:

PHP message: PHP Fatal error: Uncaught UnexpectedValueException: The stream or file "/var/www/my_project/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied in /var/www/my_project/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107
Stack trace:
#0 /var/www/my_project/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(37): Monolog\Handler\StreamHandler->write(Array)
#1 /var/www/my_project/vendor/monolog/monolog/src/Monolog/Logger.php(337): Monolog\Handler\AbstractProcessingHandler->handle(Array)
#2 /var/www/my_project/vendor/monolog/monolog/src/Monolog/Logger.php(616): Monolog\Logger->addRecord(400, Object(Symfony\Component\Debug\Exception\FatalErrorException), Array)
#3 /var/www/my_project/vendor/laravel/framework/src/Illuminate/Log/Writer.php(202): Monolog\Logger->error(Object(Symfony\Component\Debug\Exception\FatalErrorE

 

Trong quá trình tìm hiểu tôi đã tìm ra được vấn đề. Đó là SELinux trên môi trường CentOS, SELinux được cài mặc định khi sử dụng ProfitBricks CentOS 7 image. Để tìm hiểu SELinux là gì các bạn có thể xem tại đây.

Tiếp theo tôi sẽ giải quyết lỗi Permission denied  khi cài Laravel.
Đầu tiên phải kiểm tra xem SELinux có đang được bật trên server của bạn không:

sudo sestatus

Và kết quả trả về sẽ tương tự như này:

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28

 

Nếu SELinux status enable và Current mode enforcing thì cách phương pháp dưới đây sẽ giải quyết vấn đề bạn đang gặp phải.

Lỗi này có thể được gây ra bởi ownership với folder và file, security context đang được thực hiện bởi SELinux trên một vài folder mà Laravel cần ghi vào. Tôi có thể giải quyết vấn đề này bằng cách chạy:

sudo chown -R apache:root /var/www/my_project/storage/*
sudo chown -R apache:root /var/www/my_project/bootstrap/cache

Điều này thay đổi quyền sở hữu của những thư mục đó thành apache.

Để giải quyết vấn đề SELinux, chúng ta cần cập nhật security context từ httpd_sys_content_t thành httpd_sys_rw_content_t. Điều này có thể được thực hiện bằng cách chạy semanage, đây là một phần của gói policycoreutils-python. (Bạn có thể cài đặt nó bằng lệnh sudo yum install policycoreutils-python nếu cần, nhưng nó đã được cài đặt khi sử dụng image của CentitBricks CentOS 7.)

sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/my_project/bootstrap/cache(/.*)?'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/my_project/storage(/.*)?'

 

Để apply những thay đổi đó, chạy lệnh:

sudo restorecon -Rv '/var/www/my_project'

Cuối cùng bạn chạy lệnh ls -Z để xem những thay đổi với folder và file. Bạn sẽ thấy storage hiển thị httpd_sys_rw_content_t thay vì httpd_sys_content_t. Điều tương tự cũng đúng với các thư mục trong bootstrap.

Bây giờ bạn có thể load lại website và xem kết quả.

Goodluck!

 

Nguồn tham khảo: Profitbricks