こんにちは。
先日、AWSにてLaravel+Vueのサービスをデプロイした時に「Can't write image data to path」というエラーが出てハマったので、その対処法を備忘録がてら。
結論:大体、どっちか
1:ディレクトがない
2:権限がない
当方では、Laravel5.8(という2023年時点で使ってるやついるんか?ってレベルの古いバージョン)で作成しており
intervention/image というモジュールを使って画像の圧縮や、拡張子の変更などを行おうとしておりました。。
んで、「ローカル環境ではそれで問題なく画像の保存が出来ていたのに、AWSにデプロイしたら出来なくなった。」
って状況になったので、その時の悪戦苦闘した内容の結論部分だけ。
1:ディレクトリがない
そもそも、「Can't write image data to path」というエラーは文章そのままの意味で
「パスにイメージの書き込みができない」ってことなので、パスの間違い
例えばタイポとか、そんなディレクトリ作ってないわ。ってパターンなら当然ですね。
意外と(AWSに限らず)デプロイした後、ディレクトリが作られてなかったりしてなるパターンもあるかも。。
また、Laravelは「ルートディレクトリ/storage/app/public」が保存先のデフォルトに設定されているようです。
なので、その配下に作ったディレクトリに画像を保存して、表示などを行う際にシンボリックリンクを作成する必要性があるパターンが多いはず。
php artisan storage:link
を入力して、「The [public/storage] directory has been linked.」のように言われればOK
ls -la
とかで確認すると
lrwxrwxrwx 1 yutanpo yutanpo 38 10月 12 17:04 storage -> /var/www/html/アプリ名/storage/app/public
のようになっているはず。こうなっていればリンク(ショートカット的な)が作られて、画像を表示する際にstorageも参照してくれます。
ちなみに、「そもそもstorageじゃなくpublic配下に画像保存したいわ。」みたいな場合は、設定をイジる必要があります。
/config/filesystem.php
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
おそらく初期はこんな感じになっているところを
'disks' => [
'local' => [
'driver' => 'local',
'root' => /var/www/html/アプリ名/public/保存したいディレクトリ名',
],
'public' => [
'driver' => 'local',
'root' => /var/www/html/アプリ名/public/保存したいディレクトリ名',
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
のようにすることで、デフォルトの保存先のパスを変更することが可能です。
2:権限がない
私はこれでハマりました。
私はAWSにデプロイする時にapacheを使っていたんですが、この「apacheにstorageの権限を渡す」のを失念して、全て自分の権限にしてたのでこのエラーになっていました。
※今回、作成したサービスのルートディレクトリ配下には以下のように2つの「public」が存在するとします。
● ルートディレクトリ/public/images
● ルートディレクトリ/storage/app/public/images
(ルートディレクトリで)
$ sudo chown -R apache:apache storage/
$ sudo chmod -R 777 storage/
$ sudo chown -R apache:apache public/images
$ sudo chmod -R 777 public/images
のようにしてストレージ以下(正しいかは定かではない)の権限をアパッチさんに。
私の場合、public/imagesからサイト表示に使う画像等(ロゴとか)を入れていたので、ここの権限もあげちゃう。
これで数時間溶かした。。
サーバーでいじれるようにしとかなきゃダメって事だ二ャ