MetaPii 技術室

あなたの知恵と思いを検索するフラッシュメモアプリMetaPiiのエンジニアブログです。

Ubuntuで構築したDocker Laravel のファイル権限 (www-data User access denied) 問題の即席対応

環境

概要

みんなどうしているんですかね。
Ubuntu上のDocker Laravelでnginxを通してアクセスするとwww-dataユーザー(UID=82)ってやつの権限(所有権)じゃないとNot Foundやaccess deniedになる問題。
とりあえず、時間がない中で数ヶ月走りながら運用してみて、とりまこれでのりきっとけってレベルの短期的な対応方法を記載します。

最初の問題点

  • 立ち上げた初期時点はNot Foundやaccess denied

    1. 対応:即席レベル1(Not Foundやaccess deniedの解消)

    まず、速攻の対応としては単に権限変更すればアクセス問題は解決します。
    例えば、以下のvolume設定でアプリを立ち上げているとします。

# docker-compose.yml
  app:
    build:
      context: .
      args:
        - TZ=${TZ}
    restart: always
    ports:
      - ${APP_PORT}:8000
    depends_on:
      - db
    volumes:
      - .src:/work

であれば作業ルート(/work)に対して所有権を変更するだけです。
publicは別途、権限変更。

$ docker-compose exec app chown -R www-data:www-data /work
$ docker-compose exec app chmod +x /work/public

でもこれだとコードの修正がローカルからはできません。
なので、コードの修正するときは以下の対応2をします。

2. 対応:即席レベル1(ローカルからのコード修正)

ローカルのユーザー名はdevとします。
その場合以下のコマンドで一発解決。

$ sudo chown -R dev:dev ./src

私は事情もあって実際これで2ヶ月くらい運用しました。
アクセスするとき、コード編集するときはいちいち上記のコードを実行してました。
いやぁ辛かったぁ。

次の問題点

  • アクセスするときはwww-dataへ、コード修正するときはローカルのユーザーへいちいち権限変更するのがとてつもなく面倒

    3. 対応:即席レベル2(グループを作成する)

    さて、それでLinuxのグループのノウハウを蓄積して少し進化させました。
    方法としては、
    1. docker上のwww-dataユーザー(UID=82)とそのグループ(dockerグループ)をローカルのUbuntu上に作成
    2. ローカルのユーザーを上記のdockerグループに参加させる
    3. 作業ファイルの権限をdockerグループレベルで編集可能にする

というやり方です。
これだといちいち権限の変更作業がないです。
残る問題としては、新規でコンテナ上のユーザーでファイルを作成したときrootとか権限自体がグループレベルで変更できない初期設定だったり。 この問題は追々対応します。

3-1. www-dataユーザー作成

コンテナ上のwww-dataユーザーのUIDをまず調べます。

$ docker-compose exec app cat /etc/group | grep www
www-data:x:82:www-data

次に、ローカル(Ubuntu)上でそのユーザとグループを作成します。 調べたUIDを使います。
名前は別にwww-dataでなくもいいです。私はdockerの省略系でdocにしました。

$ sudo useradd --shell /bin/bash -u 82 -o -m doc
$ sudo groupmod -g 82 doc

3-2. ローカルのグループへ参加させる

上記で作成したdocグループにローカルユーザーであるdevを参加させます。

sudo gpasswd -a dev doc

3-3. グループ編集可能に権限変更

これでまずはwww-dataへ変更させ、今後はwww-dataの所有権でやっていきます。

$ docker-compose exec app chown -R www-data:www-data /work

最後に、編集したいディレクトリに対して以下のコマンドでグループ編集可にします。

$ sudo chmod -R 770 ./src

上記はすべてのファイルに対して再帰的にやっちゃってますが、個別のフォルダにかける場合でもおkです。
なぜなら所有はwww-dataになってるのでアクセスは常にできるようになってます。

余談

あとは新規作成時の問題どうするかなぁ。