1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Docker × Laravel開発】 よくあるホストとの権限問題をまとめてみた

1
Posted at

1.はじめに

Laravelに限らずですが、Docker環境で開発していると以下のような権限トラブルに遭遇しがちです。

  • php artisan系のコマンドで動かないものがある
  • storageの書き込み,閲覧ができない
  • Permission deniedが頻発する

「ローカルでは動くのにDockerだと動かない」「突然ファイルに書き込めなくなった」 そのほとんどは権限問題です。

この記事では、よくあるケースとその原因・解決方法をまとめます。

前提知識: Dockerファイル権限の仕組み

コンテナ内のプロセスはデフォルトでrootとして動く

DockerfileでUSERを指定しない場合、コンテナ内のプロセスはUID 0(root)で実行されます。
この状態でファイルを作成すると、ホスト側でもroot所有のファイルになります。

ボリュームマウントとUID

DockerのボリュームマウントはUIDベースでファイル権限を管理します。ユーザ名ではなくUIDで一致判定されるため、ホスト側のUID 1000とコンテナ側のUID 1000は、ユーザ名が異なっていても同じユーザとして扱われます。

ホスト: youarname(UID=1000)が所有するファイル
コンテナ: appuser(UID=1000)が所有するファイルとして見える
→UIDが同じなので読み書き可能

解決方法

先に権限問題に対する解決方法をお伝えすると以下の方法になります。

方法A: UID/GIDをホストと一致させる(推奨)

dockerfile
ARG UID=1000
ARG GID=1000
RUN groupadd -g ${GID} appgroup \
    && useradd -u ${UID} -g ${GID} -m appuser
docker-compose.yml
backend:
  build:
    context: ./docker/backend
    args:
      UID: ${UID}
      GID: ${GID}
  user: "${UID}:${GID}"
  volumes:
    - ./backend:/var/www

方法B: ホスト側でディレクトリの権限を変更する

chmod -R 775 backend/storage backend/bootstrap/cache

方法Bは手軽なのですが、チーム開発では全員が同じ操作をする必要もあり、gitでの管理もしにくいので方法Aが推奨です。

権限問題が発生する様々なケース

以降は権限関連で発生する代表的な5ケースをご紹介します。

ケース1:storageやbootstrap/cacheに書き込めない

エラー内容

The stream or file "/var/www/storage/logs/laravel.log" could not be opened  
in append mode: Failed to open stream: Permission denied

や

file_put_contents(/var/www/bootstrap/cache/packages.php):  
Failed to open stream: Permission denied

原因

Laravelは以下のディレクトリに書き込み権限が必要です。(閲覧する場合は閲覧権限も)

  • storage/app/
  • storage/framework/cache/
  • storage/framework/sessions/
  • storage/framework/views/
  • storage/logs/
  • bootstrap/cache/

コンテナ内のプロセスのUID/GIDと、これらのディレクトリの所有者が一致しない場合に権限エラーが発生します。

ケース2: php artisan tinkerが動かない

エラー内容

ErrorException
Writing to directory /.config/psysh is not allowed.

原因

docker-compose.ymlでuser: "1000:1000"を指定しているが、コンテナ内にUID 1000のユーザーが存在しないケースです。
ユーザーが存在しないUIDでプロセスを実行すると、ホームディレクトリが解決できません。
tinkerが内部で使うpsyshは設定ファイルを~/.config/psyshに保存しようとしますが、~が不明なためルート直下の./config/psyshに下記行もとして権限エラーになります。

ケース3: composer installで権限がおかしくなる(頻発)

問題

composer install後にvendor/*ディレクトリがroot所有になり、アプリケーションやその後のcomposer`コマンドでエラーが発生する。

[ErrorException]
file_put_contents(/var/www/vendor/composer/installed.json): Failed to open stream: Permission denied

ケース4: chownがボリュームマウントで無効になる

問題

Dockerfileでchownを実行しても反映されない

Dockerfile
WORKDIR /var/www
COPY . .
RUN chown -R appuser:appgroup /var/www

原因

docker-compose.ymlでボリュームマウントしている場合、コンテナ起動時にホスト側のディレクトリがコンテナ内のディレクトリを上書きしているため。

ケース5: artisanコマンドで生成したファイルの所有者がおかしい(頻発)

問題

php artisan make:controller等で生成されたファイルがroot所有になり、エディタで編集できない。

まとめ

  • UID/GIDをホストと一致させる
  • コンテナ内にユーザーを作成する
  • rootでの操作をさける

権限問題の多くは「コンテナ内のUIDとホスト側のUIDが一致しない」ことが原因です。
UID/GIDの一致を最初に設定しておけば、大半のトラブルを未然に防ぐことができます。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?