file_put_contents failed to open stream: Permission deniedを解決する方法【Laravel】
Laravelのfile_put_contents(storage/framework/views/…): Failed to open stream: Permission deniedの解決方法です。chmod -R 777で解決した体験と、2026年11月にLaravel 13で確かめた、所有者を実行ユーザーに合わせる直し方とエラー文の変化をまとめました。
エラー文
file_put_contents(/var/www/html/laravel-docker/src/storage/framework/views/b560c9abc12f714c866236b477e2d6a6.php): Failed to open stream: Permission denied
解決方法(実際に解決した方法)
storage ディレクトリに対して、権限を与えることで解決しました。
chmod -R 777 storage当時はこれで画面が表示されるようになりました。
ただ、777 は「誰でも読み書き・実行できる」設定です。
本番のサーバーでは、今はおすすめしません。
下の「2026年11月にLaravel 13で確かめたこと」で、所有者を Web サーバーの実行ユーザーに合わせる直し方を試しているので、そちらを先に検討してください。
エラーの原因
システムが、storage配下のファイルに対して、読み書きする権限がないためこのエラーが発生します。
なので、storage ディレクトリに対して、権限を与えることで解決します。
ここでいう「システム」は、PHP を動かしているユーザー(Web サーバーや PHP-FPM の実行ユーザー)のことです。
ファイルを作ったユーザー(root や自分のユーザー)と、PHP を動かすユーザーが違うと、このエラーになります。
2026年11月にLaravel 13で確かめたこと
2026年11月に、Docker の php:8.4-cli(PHP 8.4.27)・Laravel 13.40.0 で、エラーを起こしてから直るまでを確かめました。
ファイルを root の所有・755 にしたまま、php artisan serve を www-data ユーザーで動かすと、トップページは 500 エラーになりました。
(初期設定のセッションの保存先は SQLite のデータベースなので、database ディレクトリだけは www-data が書き込めるようにしてあります。)
今のLaravelではエラー文がtempnam()に変わる
このとき表示されたエラー文は、file_put_contents ではなく次のものでした。
tempnam(): file created in the system's temporary directoryスタックトレースを見ると、storage/framework/views に Blade のコンパイル結果を書こうとして失敗していました。
at tempnam('/var/www/app/storage/framework/views', '2ef0ce1b5d3ef6a4ad86e1d56f265c2a.php')Laravel のソースを見比べると、ビューのコンパイル結果の書き込み方が変わっていました。
- Laravel 11.30.0・12.0.0:
$this->files->put()(中でfile_put_contents())で書き込む(v11.30.0 の BladeCompiler.php) - Laravel 12.71.0・13.40.0:
$this->files->replace()(一時ファイルをtempnam()で作ってから置き換える)で書き込む(v13.40.0 の BladeCompiler.php)
そのため、同じ「storage に書き込めない」状態でも、今の Laravel ではビューのところで tempnam() のエラーが出ます。
書き込めない場合、一時ファイルはシステムの一時ディレクトリ(今回は /tmp)に空のまま残っていました。
セッションをfileにしているとfile_put_contentsのエラーになる
.env を SESSION_DRIVER=file にして、ビューはあらかじめ php artisan view:cache でコンパイルしておくと、今の Laravel 13 でも file_put_contents のエラーになりました。
file_put_contents(/var/www/app/storage/framework/sessions/bgfkZCrkYwGHWjnZhUCZuLDM2RtznaVrB1b2tQQf): Failed to open stream: Permission deniedどこに書き込めないかで、エラー文のパスが storage/framework/views や storage/framework/sessions に変わります。
パスを見れば、権限が足りないディレクトリが分かります。
ログ(storage/logs/laravel.log)に書き込めない場合は、次のエラーになりました。
The stream or file "/var/www/app/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission deniedchmod -R 777でも、所有者を合わせても直る
上の状態から、元の方法の chmod -R 777 storage を実行すると、トップページは 200 で表示されました。
次に、もう一度 root の所有・755 に戻してから、所有者を実行ユーザー(www-data)に合わせる方法を試しました。
chown -R www-data:www-data storage bootstrap/cache
chmod -R 775 storage bootstrap/cacheこちらでも 200 で表示され、セッションのファイルは www-data の所有で作られていました。
-rw-rw-r-- 1 www-data www-data 141 Nov 5 19:05 4Y0ZjTttdgFf66fgmXmxzpd5aokrl2oC2SdimPNJ777 にしなくても、PHP を動かすユーザーが書き込めれば直ります。
bootstrap/cache も一緒に変えているのは、Laravel がここにもキャッシュを書き込むためです(下の「参考」の公式ドキュメント)。
rootでartisanを実行すると再発することがある
所有者を合わせたあとでも、root で artisan のコマンドを実行してログが出ると、laravel.log が root の所有(644)で作られました。
-rw-r--r-- 1 root root 53 Nov 5 19:04 storage/logs/laravel.logこの状態で www-data がログを書こうとすると、上の「could not be opened in append mode」のエラーになりました。
chown www-data:www-data storage/logs/laravel.log で所有者を戻すと、書き込めるようになりました。
一度直ったのにまた出る場合は、ls -l で storage の中に root の所有のファイルが増えていないかを見てください。
macOSのDocker Desktopのマウントでは起きなかった
最初、macOS の Docker Desktop で、Mac のフォルダをマウントした中の Laravel で同じことを試しましたが、エラーは起きませんでした。
ファイルの所有者は root と表示されているのに、www-data で書き込めました。
マウントの種類は fakeowner と表示されていて、所有者による権限の確認が効いていないようです。
そのため、上の確かめはコンテナの中のディレクトリ(/var/www/app)にコピーしてから行いました。
同じ Docker の構成でも、Mac では起きず、Linux のサーバーなどで起きる、ということがありえます。
参考:公式ドキュメントのディレクトリの権限
Laravel 13.x の公式ドキュメント(Deployment)の「Directory Permissions」では、Laravel は bootstrap/cache と storage に書き込む必要があるので、Web サーバーのプロセスの所有者がこれらに書き込めるようにする、とのことです。
上の確かめでは実行ユーザーを www-data にしましたが、実際の名前はサーバーの構成によって変わるはずなので、自分の環境で PHP を動かしているユーザーを確かめてから chown してください。
もっと詳しく
storage とは?
Laravel プロジェクトをインストールした際に、以下のようなディレクトリ構成が完成したと思います。
├── app
│ ├── Console
│ ├── Exceptions
│ ├── Http
│ │ ├── Controllers
│ │ ├── Middleware
│ ├── Models
│ ├── Providers
├── bootstrap
│ ├── cache
├── config
├── database
│ ├── factories
│ ├── migrations
│ ├── seeders
├── public
│ ├── index.php
├── resources
├── routes
├── storage ←これ
│ ├── app
│ ├── framework
│ │ ├── cache
│ │ ├── sessions
│ │ ├── testing
│ │ └── views
│ ├── logs
├── tests
├── vendor
├── .env
├── .env.example
略この中にstorageというディレクトリがあります。
このディレクトリには、例えば
- ログを出力
- 様々なデータをキャッシュデータが保存される
- キャッシュデータを読み込む
というような役割があり、その結果画面が表示されています。
なので、権限がないと本件のエラーになります。
ディレクトリ位置を間違えないように気を付ける
初歩的なミスとしてありがちな内容です。
さきほど説明したとおりstorageに権限を与えなければならないので、ファイルの指定の際には、相対パスに気を付ける必要があります。
chmod -R 777 相対パス必要があれば、
cd laravel-projectにディレクトリ移動して、chmodのコマンドを打ちましょう。
chown で所有者を合わせる場合も同じで、Laravel プロジェクトの直下で実行します。
以上、誰かの参考になれば幸いです。




