コンテナ内で作られたファイルがrootとなり権限エラーで編集できなくなってしまう問題の処方箋

# はじめに
https://qiita.com/nagareboshi/items/e09cf8305654efbf9899

こちらの記事でUbuntu内ですべて完結すると処理が速くなると紹介しましたが、そうした場合デメリットがあります。
コンテナ内で作られたファイルは特に何もしなければrootユーザーとしてファイルが作られてしまうため、ホスト側からはファイル権限エラーとなり、編集することができなくなってしまいます。

今回はファイル権限まわりについて調べたことを記事としてまとめたいと思います。

# 動作確認環境
- Windows10 Home
- wsl2
- Docker Desktop for Windows
- Ubuntu20.04 LTS
- Laravel8
- PhpStorm


# Ubuntu側にコードの実体があり、それをコンテナにマウントした場合
先の記事で紹介した通り、こちらの方法の場合、無駄な変換処理などが行われないため処理がとても速くなります。
しかしながらこちらの方法の場合、特に何もしなければコンテナ内の操作はすべてroot権限で実行されるため、コンテナ内でコマンドなどで作成したファイルはホスト側から権限問題で編集できなくなります。

- コンテナ側

```bash
drwxr-xr-x  7 root root   4096 Aug 10 17:27 app
-rwxr-xr-x  1 root root   1686 Aug 10 17:27 artisan
drwxr-xr-x  3 root root   4096 Aug 10 17:27 bootstrap
-rw-r--r--  1 root root   1699 Aug 10 17:27 composer.json
-rw-r--r--  1 root root 282741 Aug 11 01:55 composer.lock
drwxr-xr-x  2 root root   4096 Aug 10 17:27 config
drwxr-xr-x  5 root root   4096 Aug 10 17:27 database
-rw-r--r--  1 root root    258 Aug 10 17:27 .editorconfig
-rw-r--r--  1 root root    920 Aug 11 01:55 .env
-rw-r--r--  1 root root    869 Aug 10 17:27 .env.example
-rw-r--r--  1 root root    111 Aug 10 17:27 .gitattributes
-rw-r--r--  1 root root    207 Aug 10 17:27 .gitignore
-rw-r--r--  1 root root    473 Aug 10 17:27 package.json
-rw-r--r--  1 root root   1202 Aug 10 17:27 phpunit.xml
drwxr-xr-x  2 root root   4096 Aug 10 17:27 public
-rw-r--r--  1 root root   3851 Aug 10 17:27 README.md
drwxr-xr-x  6 root root   4096 Aug 10 17:27 resources
drwxr-xr-x  2 root root   4096 Aug 10 17:27 routes
-rw-r--r--  1 root root    563 Aug 10 17:27 server.php
drwxr-xr-x  5 root root   4096 Aug 10 17:27 storage
-rw-r--r--  1 root root    181 Aug 10 17:27 .styleci.yml
drwxr-xr-x  4 root root   4096 Aug 10 17:27 tests
drwxr-xr-x 44 root root   4096 Aug 11 01:55 vendor
-rw-r--r--  1 root root    559 Aug 10 17:27 webpack.mix.js
```

- Ubuntu側

```bash
-rw-r--r--  1 root        root           258 Aug 11 02:27 .editorconfig
-rw-r--r--  1 root        root           920 Aug 11 10:55 .env
-rw-r--r--  1 root        root           869 Aug 11 02:27 .env.example
-rw-r--r--  1 root        root           111 Aug 11 02:27 .gitattributes
-rw-r--r--  1 root        root           207 Aug 11 02:27 .gitignore
-rw-r--r--  1 root        root           181 Aug 11 02:27 .styleci.yml
-rw-r--r--  1 root        root          3851 Aug 11 02:27 README.md
drwxr-xr-x  7 root        root          4096 Aug 11 02:27 app/
-rwxr-xr-x  1 root        root          1686 Aug 11 02:27 artisan*
drwxr-xr-x  3 root        root          4096 Aug 11 02:27 bootstrap/
-rw-r--r--  1 root        root          1699 Aug 11 02:27 composer.json
-rw-r--r--  1 root        root        282741 Aug 11 10:55 composer.lock
drwxr-xr-x  2 root        root          4096 Aug 11 02:27 config/
drwxr-xr-x  5 root        root          4096 Aug 11 02:27 database/
-rw-r--r--  1 root        root           473 Aug 11 02:27 package.json
-rw-r--r--  1 root        root          1202 Aug 11 02:27 phpunit.xml
drwxr-xr-x  2 root        root          4096 Aug 11 02:27 public/
drwxr-xr-x  6 root        root          4096 Aug 11 02:27 resources/
drwxr-xr-x  2 root        root          4096 Aug 11 02:27 routes/
-rw-r--r--  1 root        root           563 Aug 11 02:27 server.php
drwxr-xr-x  5 root        root          4096 Aug 11 02:27 storage/
drwxr-xr-x  4 root        root          4096 Aug 11 02:27 tests/
drwxr-xr-x 44 root        root          4096 Aug 11 10:55 vendor/
-rw-r--r--  1 root        root           559 Aug 11 02:27 webpack.mix.js
```

# Windows上（CドライブやDドライブ）のデータをコンテナにマウントした場合
先の記事で紹介した通り、Windows側のファイルをコンテナとマウントした場合、処理が著しく重くなります。
その反面、Windows側にコードの実体がある場合は、コンテナ内でrootユーザーがファイルを作成したとしてもWindowsがその権限を無視してくれる（同じUIDでファイルを生成してくれる、777権限となる）ため権限上のトラブルに見舞われることはありません。
早い話こちらの方法の場合、重いけれど何も意識しなくても普段どおりコード編集ができます。

- コンテナ側

```bash
-rwxrwxrwx 1 1000 1000    258  8月 11 02:27 .editorconfig
-rwxrwxrwx 1 1000 1000    920  8月 11 11:08 .env
-rwxrwxrwx 1 1000 1000    869  8月 11 02:27 .env.example
-rwxrwxrwx 1 1000 1000    111  8月 11 02:27 .gitattributes
-rwxrwxrwx 1 1000 1000    207  8月 11 02:27 .gitignore
-rwxrwxrwx 1 1000 1000    181  8月 11 02:27 .styleci.yml
-rwxrwxrwx 1 1000 1000   3851  8月 11 02:27 README.md
drwxrwxrwx 1 1000 1000   4096  8月 11 02:27 app
-rwxrwxrwx 1 1000 1000   1686  8月 11 02:27 artisan
drwxrwxrwx 1 1000 1000   4096  8月 11 02:27 bootstrap
-rwxrwxrwx 1 1000 1000   1699  8月 11 02:27 composer.json
-rwxrwxrwx 1 1000 1000 282741  8月 11 11:05 composer.lock
drwxrwxrwx 1 1000 1000   4096  8月 11 02:27 config
drwxrwxrwx 1 1000 1000   4096  8月 11 02:27 database
-rwxrwxrwx 1 1000 1000    473  8月 11 02:27 package.json
-rwxrwxrwx 1 1000 1000   1202  8月 11 02:27 phpunit.xml
drwxrwxrwx 1 1000 1000   4096  8月 11 02:27 public
drwxrwxrwx 1 1000 1000   4096  8月 11 02:27 resources
drwxrwxrwx 1 1000 1000   4096  8月 11 02:27 routes
-rwxrwxrwx 1 1000 1000    563  8月 11 02:27 server.php
drwxrwxrwx 1 1000 1000   4096  8月 11 02:27 storage
drwxrwxrwx 1 1000 1000   4096  8月 11 02:27 tests
drwxrwxrwx 1 1000 1000   4096  8月 11 11:07 vendor
-rwxrwxrwx 1 1000 1000    559  8月 11 02:27 webpack.mix.js
```

- Ubuntu側

```bash
uid=1000(nagareboshi) gid=1000(nagareboshi) groups=1000(nagareboshi)
```

```bash
-rwxrwxrwx 1 nagareboshi nagareboshi    258 Aug 11 02:27 .editorconfig*
-rwxrwxrwx 1 nagareboshi nagareboshi    920 Aug 11 11:08 .env*
-rwxrwxrwx 1 nagareboshi nagareboshi    869 Aug 11 02:27 .env.example*
-rwxrwxrwx 1 nagareboshi nagareboshi    111 Aug 11 02:27 .gitattributes*
-rwxrwxrwx 1 nagareboshi nagareboshi    207 Aug 11 02:27 .gitignore*
-rwxrwxrwx 1 nagareboshi nagareboshi    181 Aug 11 02:27 .styleci.yml*
-rwxrwxrwx 1 nagareboshi nagareboshi   3851 Aug 11 02:27 README.md*
drwxrwxrwx 1 nagareboshi nagareboshi   4096 Aug 11 02:27 app/
-rwxrwxrwx 1 nagareboshi nagareboshi   1686 Aug 11 02:27 artisan*
drwxrwxrwx 1 nagareboshi nagareboshi   4096 Aug 11 02:27 bootstrap/
-rwxrwxrwx 1 nagareboshi nagareboshi   1699 Aug 11 02:27 composer.json*
-rwxrwxrwx 1 nagareboshi nagareboshi 282741 Aug 11 11:05 composer.lock*
drwxrwxrwx 1 nagareboshi nagareboshi   4096 Aug 11 02:27 config/
drwxrwxrwx 1 nagareboshi nagareboshi   4096 Aug 11 02:27 database/
-rwxrwxrwx 1 nagareboshi nagareboshi    473 Aug 11 02:27 package.json*
-rwxrwxrwx 1 nagareboshi nagareboshi   1202 Aug 11 02:27 phpunit.xml*
drwxrwxrwx 1 nagareboshi nagareboshi   4096 Aug 11 02:27 public/
drwxrwxrwx 1 nagareboshi nagareboshi   4096 Aug 11 02:27 resources/
drwxrwxrwx 1 nagareboshi nagareboshi   4096 Aug 11 02:27 routes/
-rwxrwxrwx 1 nagareboshi nagareboshi    563 Aug 11 02:27 server.php*
drwxrwxrwx 1 nagareboshi nagareboshi   4096 Aug 11 02:27 storage/
drwxrwxrwx 1 nagareboshi nagareboshi   4096 Aug 11 02:27 tests/
drwxrwxrwx 1 nagareboshi nagareboshi   4096 Aug 11 11:07 vendor/
-rwxrwxrwx 1 nagareboshi nagareboshi    559 Aug 11 02:27 webpack.mix.js*
```

# 補足知識
Dockerへのアクセスは、引数として指定しなければrootでアクセスします。

```bash
# appというコンテナに対してコマンドを実行する例
# この指定の場合、rootユーザーとしてコマンドが実行されます
docker compose exec app *********
```

rootユーザーでログインした状態でファイルを作ると、そのファイルはroot権限となり、そのままホストマシンでもこの設定が受け継がれます。

# 改善方法1
編集できなくなっているのは、ファイルの権限がrootになっていることが原因のため、この権限を変えることで改善することができます。

```bash
chown -R {ユーザー名}:{ユーザー名} 権限を変更したい対象
```

# 改善方法2
ファイルが編集できなくなっているのはコンテナ内にrootユーザーとしてログインし、rootユーザーでファイル作成してしまっていることが原因のため、コンテナに新たなユーザーを作成することで改善することができます。

- 新規ユーザーを作成する例（Dockerfileに下記を追加）

```bash
# 1000という数値はUbuntu側でidコマンドを入力した時に表示される情報を指定します
# 特別な変更等を加えてなければ、Ubuntuで初期に作られるユーザーは1000になっています
RUN groupadd --force -g 1000 {Ubuntu側のユーザー名}
RUN useradd -ms /bin/bash --no-user-group -g {Ubuntu側のユーザー名} -u 1000 {Ubuntu側のユーザー名}

# phpの場合に限りますが、Composerを新規ユーザーで叩けるようにしたいため、権限をあわせて変更します
RUN chmod -R ugo+rw /composer
```

- ユーザーの切り替え

```bash
# コンテナ内で下記コマンドを実行する
su {ユーザー名}
```

- 新規ユーザーでコンテナにアクセスする

```bash
# コマンド
docker compose exec --user {ユーザー名} {コンテナ名} bash

# コマンド例
docker compose exec --user nagareboshi app bash
```


# 参考ページ
https://mrkmyki.com/%E9%80%86%E5%BC%95%E3%81%8Ddocker/docker-docker-compose-exec%E3%81%A7%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%99%E3%82%8B%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B

https://tech-blog.rakus.co.jp/entry/20200826/docker

https://github.com/laravel/sail/blob/1.x/runtimes/8.0/Dockerfile

https://wonwon-eater.com/docker-non-root/

https://zenn.dev/rotelstift/articles/docker-for-windows-permission

https://unskilled.site/docker%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E5%86%85%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%A8%E3%83%9B%E3%82%B9%E3%83%88%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%A8%E3%81%AE%E9%96%A2%E4%BF%82/