WSL2とDockerコンテナのユーザをrootに統一することで権限問題から解放されたい


## こんな人向けの記事

- なぜかパワフルなWindows環境を持っている方(SteamOSの開発がんばれ！)
- 普段はMacをつかってローカル／コンテナ内を意識せず開発できているのに、同じことをWSL2環境(というか本物のLinux環境)でやろうとすると権限権限とうるさい！とお嘆き方
- コンテナはalpineを使いたい

## たどり着いたGoal

- WSL2とdockerコンテナ両方のユーザをrootで統一することで権限問題を回避できた
- （私の環境では）権限問題が回避できたのでMacで動かしているdockerファイル/docker-composeファイルをそのままWSL2環境で利用できた

## やっていないこと／説明されていないこと

- そもそも root で統一していいのか？という疑問を解消すること
- dockerコンテナ側をrootで動かす手順には触れません[^1]

[^1]:docker hubで用意されている公式イメージは基本的にrootで動くと思います。

## 以下の手順で試した環境

下記は私が試したときの一例です。

- Windows10環境
- WSL2 + Dockerで動かす環境は構築済み
- コンテナは rails7 + postgresql で動かした

## 手順

手順としてはすごくシンプルで、WSL2環境をrootで動かすだけです。
ただ既存のWSL2の仮想環境を設定変更するのは抵抗があるので専用に仮想マシンに構築します。

### 1. 開発環境をインポートする

ここでは仮想環境名を `rails-env` とします

まず、現時点(2022/04/22)の最新バージョンであるUbunto21.04のクラウドイメージを [ここ](https://cloud-images.ubuntu.com/releases/hirsute/release/) からファイル名が ～wsl.rootfs.tar.gz となっているものの中から自分のCPUに合わせてダウンロードします。



下記の例では %HOMEPATH% 以下のようなフォルダ構成であることを想定しています。

```
%HOMEPATH%
　├ ws/
　│  ├ env/ <-- フォルダだけでOK.
　│  └ rootfs/
　│　　　└ ubuntu-21.04-server-cloudimg-amd64-wsl.rootfs.tar.gz
```

なお、 %HOMEPATH% の実際のパスはコマンドプロンプトで `echo %HOMEPATH%` などで確認してください。

それでは、下記のように `コマンドプロンプト` 上でダウンロードしたファイルをインポートしましょう。

```dosbatch:コマンドプロンプト
> wsl --import rails-env %HOMEPATH%\wsl\env\rails-env %HOMEPATH%\wsl\rootfs\ubuntu-21.04-server-cloudimg-amd64-wsl.rootfs.tar.gz --version 2
```

インポート結果を確認します。下記コマンドで `rails-env` が確認できると思います。

```dosbatch:コマンドプロンプト
> wsl -l -v
```

確認出来たら下記コマンドで起動できます。

```dosbatch:コマンドプロンプト
> wsl -d rails-env
```

ちなみに、仮想環境の停止は以下のコマンドで行えます

```dosbatch:コマンドプロンプト
> wsl -t rails-env
```

### 2. WSL環境の設定

上記の手順のままだとログイン後以下のように表示されます。

```bash:
root@[host]:/mnt/c/Users/[username]#
```

気持ち悪いですね…と、それ以外にもWindows環境を引きずっているので、以下の方針で設定を変更します。

- WindowsのPATHは基本引き継がない
- ログイン後の初期ディレクトリを /root にする
- WindowsのPATHのうち必要なものだけ引き継ぐ

まずは、WindowsのPATHを引き継がないように変更します。 
`/etc/wsl.conf` を新規作成して下記のように編集します。

```bash:/etc/wsl.conf
[interop]
appendWindowsPath = false
```

設定後ログアウトして仮想マシンを再起動させれば適用されます。

```bash:
$ exit               <-- Ubuntu環境から抜ける
> wsl -t rails-env <-- 仮想マシンを停止
> wsl -d rails-env <-- 仮想マシンを起動＆ログイン
```

次にログイン後の初期ディレクトリを /root にします。

```bash:
$ echo 'cd ~' >> ~/.bashrc
```

最後にWindowsのPATHのうち必要なものだけ引き継ぐ設定を行います。例えば `explorer.exe .` などが使えるようになるので便利です。またVScodeのパスも通しておきます。

:loudspeaker: 重要: ドライブ指定や [user_name] はご自身の環境にあわせて書き換えてください。

```
$ echo export PATH=\$PATH:/mnt/c/WINDOWS/ >> ~/.bashrc
$ echo export PATH=\$PATH:\"/mnt/c/Users/[user_name]/AppData/Local/Programs/Microsoft VS Code/bin\" >> ~/.bashrc
```

ここまで済んだらいったんシェルを再起動しましょう。ログイン時の初期ディレクトリが /root になっていることが確認できると思います。

```bash:
$ exec $SHELL -l
$ pwd
/root
```

いい感じです！

### 3.新しく作成した仮想環境で Docker Desktopが使えるようにする

このままだとdockerが起動できないので以下のように設定しておきましょう。
`rails-env` をONにして Apply & Restart を忘れずに押しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/c9e4250d-572d-4247-0e88-b223e1f7a916.png)

## 仮想環境をバックアップする

せっかく作成した環境です。いつでもきれいな状況に戻れるようにバックアップを推奨します！バックアップは仮想環境をエクスポートすることで行えます。

エクスポート先およびファイル名は下記の例では `%HOMEPATH%\wsl\rootfs\rails-env.tar` です。

```dosbatch:コマンドプロンプト
$ exit
> wsl -t rails-env <-- 仮想マシンを停止
> wsl -l -v        <-- 停止状態を確認
> wsl --export rails-env %HOMEPATH%\wsl\rootfs\rails-env.tar
```

以上で基本的な環境は整いました。あとは、ご自身のプロジェクトで試されてください！

## ちょっとしたトピック

**alpine環境上でrails7を動かすときに引っ掛かった点**

- rails7 で bin/dev するときに bash が必要だった
- localhost:3000でアクセスできない…
  - rails7 初めでだったので rails newで生成される Procfile.dev の webサーバ起動に `-b 0.0.0.0` がついていないのを見落としていた
    - `web: bin/rails server -p 3000 -b 0.0.0.0` に変更

**WSL2のネットワークについて**

- Procfile.devを変更することでlocalhost:3000でアクセスできた。少し調べたらlocalhostでの接続はWSL2環境が頑張っているらしいけど、複数WSL環境が動いている状況でどうやって接続しているのだろう？
  - localhost:3000で接続できないこともよく起こるらしい。
  - 接続できないならwsl2(ubuntu)側のipアドレスで接続が可能
    - `ip r` 等で確認できる。

**Postgresについて**

- そういえば以前はWSL2環境でdockerのpostgresqlイメージを使うと initdb で権限エラーが起こった覚えが。rootで動かすようになったので気づかないうちに回避できたのだろうか？