WSL 2 の Linux ファイルシステムを bind mount してコンテナー内開発を行う場合、
権限を適切に設定しないと、
コンテナー内で作成したファイルが、ホストの WSL 2 や Windows 側で
操作できなくなってしまうなどの問題が発生します。
この記事では、
WSL 2 を利用したコンテナー内開発において
権限をどう設定するべきかについて解説します。
WSL 2 を利用したコンテナー内開発での権限の問題
初期状態では、
WSL 2 のファイルシステムを開発用コンテナーに bind mount すると、
多くの場合、コンテナー内で作成したファイルが
ホストの WSL 2 や Windows 側で操作できなくなってしまいます。
これは、権限が次のようになりやすいためです:
対象 | ユーザー権限 |
---|---|
コンテナー内で作成したファイルの所有者 | root |
WSL 2 や Windows 側からの操作 | UID 1000 |
コンテナー側のユーザー権限について知っておくべきこと
- コンテナー内は root 権限を前提に設計されていることが多いです
- そのため、Visual Studio Code のコンテナー内開発で作ったファイルは所有者が root になります
- 公開されているイメージには、
コンテナー内にユーザーや権限に関する意図的な設計がある場合もあります- 例
- Nginx 公式イメージにおける www-data ユーザー
- MySQL 公式イメージにおける mysql ユーザー
- 例
- コンテナーを実行するときに実行ユーザーを指定する方法もあります
- しかし、あまり実用的ではありません
- 今度はコンテナーが設計通りに動作しない問題を解決しなくてはならなくなります
- コンテナー内が既定のユーザー権限を前提にした設計になっていることが多いため
- 今度はコンテナーが設計通りに動作しない問題を解決しなくてはならなくなります
- しかし、あまり実用的ではありません
ホスト側のユーザー権限について知っておくべきこと
- ホスト側の WSL 2 Linux ディストリビューションは
初期設定では、UID 1000 のユーザーとして操作することになります- UID 1000 は Linux ディストリビューションの初期設定時に作成されたユーザーです
- Windows のエクスプローラーからの操作も、この UID 1000 のユーザーの扱いとなります
- Windows 側からコピーや移動して持ってきたファイルも
UID 1000 のユーザーが所有者となります
- Windows 側からコピーや移動して持ってきたファイルも
Docker 公式のベストプラクティス
Docker の公式ドキュメントでは、
権限を気にする必要があったり、ファイル・フォルダーを追加更新削除する場合、
bind mount ではなく volume を使うことを推奨しています。
ただし、同時に各所で
「bind mount は開発環境に適しています」
とも記載されています。
One case where it is appropriate to use bind mounts is during development
Where and how to persist application data | Docker development best practices | Docker Documentation
参考:
- Manage data in Docker | Docker Documentation
- Where and how to persist application data | Docker development best practices | Docker Documentation
volume を使う場合、インポートやエクスポートの処理を自作することになり、
開発の開始と終了時にこれらの処理を実行する必要があります。
参考: Use volumes | Docker Documentation
Visual Studio Code のベストプラクティス
Visual Studio Code の公式ドキュメントでは、
ユーザーと権限に関するいくつかの対策が記載されています。
中でも、新たに root 以外の実行ユーザーを作ることは
開発環境だけでなく本番環境にとっても
セキュリティー的に望ましいと解説されています。
参考: Adding a non-root user to your dev container | dvanced Container Configuration
Running your application as a non-root user is recommended
Creating a non-root user | Advanced Container Configuration
even in production (since it is more secure),
so this is a good idea even if you’re reusing an existing Dockerfile.
ただし、次のような課題もあります:
- 開発者同士でホスト側の UID を合わせる必要があります
- コンテナー内にユーザー ID を作成してから利用開始する必要があるため
公開されている Docker イメージを、そのまますぐ利用することができなくなります - 公開されている Docker イメージのユーザー権限の設計を変えることになります
WSL 2 を隔離してデフォルトユーザーを root にする
WSL 2 のデフォルトユーザーを root にすると、権限の煩雑さから解放されます。
セキュリティー的にはあまり望ましくありませんが、
次のことを考慮すると、Docker を利用する上においては、リスクは変わってないと言えます。
- WSL 2 にする前の Docker Desktop も権限的にほぼ同様の状態であること
- いずれにしてもコンテナーが root で動作していること
ただ、WSL 2 上で操作を誤ると、
権限が強いために重要なファイルを削除してしまう、といったことも考えられます。
参考: Windows 10の「WSL」の自動マウントやfstabによるマウント処理をwsl.confファイルで制御する:Tech TIPS – @IT
これを防ぐため、WSL 2 側からの Windows へのアクセスは
読み取り専用にしておくことをお奨めします。
どうやって WSL 2 のデフォルトユーザーを root にするの?
既存の Linux ディストリビューションの設定を変更する場合
1. root のパスワードを設定します
対象の Linux ディストリビューションのターミナルを起動し、
次のように入力します:
# ユーザーを root に切り替え
y-shinoda $ sudo su -
# パスワードを設定
root $ passwd
参考: Set up WSL (Ubuntu) on Windows 10 Pro | 東京大学 佐々木淳 研究室 沿岸環境学 海岸工学 環境水工学 水環境学
2. デフォルトユーザーを root に変更します
Windows PowerShell を管理者権限で起動し、
次のコマンドを実行します:
<Linux ディストリビューション名> config --default-user root
例: Ubuntu の場合:
ubuntu config --default-user root
新規 Linux ディストリビューションを設定する場合
少なくとも、Ubuntu は Windows へのインストール直後に
次の手順でデフォルトユーザーを root にできます。
1.
Microsoft Store から Windows に Ubuntu をインストールし終わったら、
Ubuntu を起動し、ターミナル上でインストール処理の完了を待ちます。
2.
インストール処理が完了し、”Enter new UNIX username:” と表示されたら
一旦、ターミナルを閉じます。
3.
再度 Ubuntu を起動すると、デフォルトユーザーが root になっています。
どうやって WSL 2 側から Windows へのアクセスを読み取り専用にするの?
WSL 2 の Linux ファイルシステム上の /etc/wsl.conf に
次の内容のファイルを作成します:
[automount]
options="metadata,umask=22,fmask=11,ro"
そして Windows を再起動します。
すると、Linux ファイルシステムで開いたシェルからは、
権限の表示は書き込み可能の表示でも、
実際に書き込みを行うと読み込み専用のファイルシステムであるエラーが発生します:
$ ls -la /mnt/c/Users/public/workspace
total 0
drwxr-xr-x 1 root root 4096 Oct 14 11:44 .
drwxr-xr-x 1 root root 4096 Oct 14 11:44 ..
-rwxr--r-- 1 root root 0 Oct 14 11:44 test1.txt
$ touch /mnt/c/Users/public/workspace/test2.txt
touch: cannot touch '/mnt/c/Users/public/workspace/test2.txt': Read-only file system
$ rm -rf /mnt/c/Users/public/workspace
rm: cannot remove '/mnt/c/Users/public/workspace/test1.txt': Read-only file system
参考:
- Windows 10の「WSL」の自動マウントやfstabによるマウント処理をwsl.confファイルで制御する:Tech TIPS – @IT
- 【 mount 】コマンド――ファイルシステムをマウントする:Linux基本コマンドTips(183) – @IT
- @IT:ファイルシステムを書き込み禁止でマウントし直すには
ちなみに、読み取り専用にするのではなく、マウント自体をやめてみたところ、
Visual Studio Code の WSL リモート開発とコンテナー内開発が動かなくなりました。
Visual Studio Code
Docker returned an error. Make sure the Docker daemon is running.
[OK]