在非 homestead 的主機上執行 laravel 時,有時會出現空白畫面,或是以下的錯誤訊息:

The stream or file "/xxxx/yyyy/zzzz/storage/logs/laravel-<日期>.log" could not be opened: failed to open stream: Permission denied

這是因為我們使用不同的方式執行 laravel 程式,會讓 log 檔有不同權限設定,和沒有檔案的寫入權限。

解法一:將 logS 目錄及檔案權限直接設為 777 (不推薦)

chmod -R 777 storage/logs/

這方法最快,但是只能治標,不能治本,有再度發生的可能;而且,還有安全性的隱憂

解法二:設計好適當的權限

以 CentOS 為例,在 CentOS 中,我們以 apache 的 virtual host 來執行我們的 laravel 系統,會有三個比較常見的狀況:
一、透過「網頁伺服器」執行程式
二、透過「命令列」執行程式
三、透過 「cron」 執行程式
各會有不同的檔案權限規則應用在新產生的檔案。我們必須針對這三種方式,來規劃不同的權限規則。

步驟一:設定群組權限

由於 網頁伺服器的預設執行帳號是 apache,所以其產生的檔案,owner及group 均是 apache;而命令列或 cron,則會根據登入的使用者帳號來設定,為了要讓不同方式產生的檔案,能透過「群組權限」的設定值來存取程式,我們必需做一些設定,假設我們 virtual host 的網頁檔案是以 john 這個帳號來登入的

# 把 john 加入 apache 群組
usermod -a -G apeche john
# 也把 apache 加入 john 群組
usermod -a -G john apache

更改群組後,shell 要重新登入;部分服務需重新開機才能套用群組權限設定

如果對於 Linux 的檔案權限不太熟悉,可以看一下鳥哥的文章 - Linux 檔案與目錄管理

步驟二:修改「網頁伺服器」的預設檔案存取權限

apache server 預設的執行帳號是 apache,產生的檔案權限為 644,範例如下:

-rw-r--r-- 1 apache apache    153438 12月 24 20:49 laravel-2019-12-24.log

我們必須設定 apache 的 umask 設定,讓其產生的檔案權限為 664,這樣一來,apache 群組才具有寫入的權限。

設定檔 umask.conf 內容

[Service]
UMask=0002

指令如下:

mkdir /etc/systemd/system/httpd.service.d
vi /etc/systemd/system/httpd.service.d/umask.conf

systemctl daemon-reload
systemctl restart httpd.service

步驟三、修改「命令列」的預設檔案存取權限

有時我們會透過 php artisan 來執行程式,產生的檔案, 其使用者和群組就是登入的帳號,而權限會根據 umask 來決定其權限。

# 在 shell 中,直接輸入 umask 可以查看目前設定
umask

# 修改 umask 為 0002
umask 0002

# 將 umask 0002 的設定加入登入設定檔
vi ~/.bashrc

步驟四、修改 「cron」 的預設檔案存取權限

當透過 cron 來進行工作排程時,其所產生的檔案,owner 和 group 是登入帳號,預設的 umask 是,0022,我們可以透過修改設定檔來改變:

# 修改設定檔,在[Service] 段中,加入 UMask=0002
vi /usr/lib/systemd/system/crond.service

systemctl daemon-reload
systemctl restart crond.service

重新啟動 cron 服務後,其所產生的檔案權限就會變為 664

解法二總結

解法二的處理方式是要達到 2 個目標
1、三種執行方式所產生的 log 檔案,不管 owner 是 apache 或是 john,其權限都是 664
2、apache 和 john 這兩個帳號,都加入對方的群組中
這樣一來,就可以無障礙的讀取 log 檔

參考資料

鳥哥的 Linux 私房菜

Laravel blank white screen

Last modified: 2020-01-02

Author

Comments

Write a Reply or Comment

Your email address will not be published.