免責
この記事の解決方法は対処療法的なものであり、本来はもっと適切なやり方がある、いわゆる「正しくない」方法である可能性があります。申し訳ございません、ご了承下さい。
私が直面した問題
最初はマウントしたディレクトリ内のファイルをWSL2側から編集できないという問題がありました。この問題には Visual Studio Code Remote - Containers を使用することで対処しました。
しかし、Reactの勉強を始めたときに、マウントしたディレクトリ上でコンテナ側から npx create-react-app my-app
を実行しても権限問題によりエラーが出力されてしまいました。これは VS Code の Remote Containers 拡張機能を使用しても解決できませんでした。
原因
この問題の原因を以下に示します。
- コンテナ側のデフォルトユーザはrootユーザ(uid=0)、コンテナ側で作成するファイル、ディレクトリの所有者もrootユーザ
- WSL2側のデフォルトユーザはWSL2ユーザ(uid=1000)、マウントしているディレクトリの所有者はWSL2のユーザ
これらから現在のユーザとファイルもしくはディレクトリの所有者が異なるという状況が発生し、権限問題が発生しているようです。
つまり、この問題を解決するには、ディレクトリやファイルの権限を変更するか、コンテナ側のユーザとWSL2のユーザを合わせる必要があります。
解決方法1
ディレクトリやファイルの権限を変更する方法です。
権限が問題となっている側(Permission deniedが発生する側)で以下のファイル及びディレクトリの所有者を変更するコマンドを実行します。
ホスト側で弾かれる場合はホスト側で問題となっているファイル及びディレクトリの所有者を変更します。
sudo chown -R $USER:$USER .
コンテナ側で弾かれる場合はコンテナ側で問題となっているファイル及びディレクトリの所有者を変更します。
chown -R root:root .
Docker公式ドキュメントの Railsアプリのセットアップ ではこの方法が使用されています。
解決方法2
docker-compose.yml を使用し、コンテナ側のユーザをWSL2のユーザに合わせる方法です。
まず docker-compose.yml
ファイルに次の記述をします。
user: "${UID_GID}"
例えば次のように記述します。
# これは例です。
version: '3'
services:
app:
build: .
tty: true
ports:
- 3000:3000
volumes:
- ./src:/app
user: "${UID_GID}"
そして docker-compose up する際に、次のようにして uid と gid を環境変数として渡します。
UID_GID="$(id -u):$(id -g)" docker-compose up
これによりコンテナ内のユーザとWSL側のユーザを一致させることができます。
試しにホスト側とコンテナ側でid
コマンドを叩き、表示される uid 及び gid が一致しているか確認してみてください。一致していれば成功です。
余談
次のコマンドをエイリアス登録しておくのがおすすめです。
alias ug='UID_GID="$(id -u):$(id -g)"'
このようにすると、 ug docker-compose up
のように ug
を頭につけるだけで docker-compose のコマンドがそのまま使えます。
参考
原因特定の参考にさせていただきました。
解決方法はここから拝借いたしました。