WSL2でDockerが動いてGUIも使える環境を作る(その2)

# はじめに

WSL2にUbuntuを導入して、Dockerやsystemd、Xserverが動く環境を作ります。3部構成でやります。
背景や環境などについては、[その1(WSL2にUbuntu-20.04をインストールする)](https://qiita.com/fjij/items/12889aaa26e03e0288e1)も参照ください。

## ゴール
- WSL2にUbuntu-20.04をインストールする。
- systemdが動くようにする(Genieの導入)。<-**本章はココ**
- Dockerを使えるようにする。<-**本章はココ**
- リモートデスクトップで接続できるようにする(xrdpの導入)。 

作業を簡単にする関係上、GenieとDockerは同じ流れでインストールします。

上から順にやっていくと何となくWSLが使えるようになることを目指していますが、うまくいかない環境がある点についてもご了承ください。

# 導入
## systemdが動くようにする
WSLではsystemdがPID1で動いていないため、systemctlなどのコマンドが使えません。Genieはこれらの問題をカバーします。以前のバージョンはDotNetのインストールが必要でしたが、現在は不要なようです。

### Genieのインストール
通常ユーザー権限でTerminalを開いた後、Genieはaptの標準リポジトリに存在していないため、リポジトリを追加します。
- リポジトリを設定に追加します。
```terminal
fjij@STELLA:~$ sudo curl -s -o /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg
fjij@STELLA:~$ sudo chmod a+r /etc/apt/trusted.gpg.d/wsl-transdebian.gpg
fjij@STELLA:~$ sudo tee /etc/apt/sources.list.d/wsl-transdebian.list << _EOF_ > /dev/null
deb https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main
deb-src https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main
_EOF_
fjij@STELLA:~$
```

- リポジトリ情報の更新とインストールを行います。
```terminal
fjij@STELLA:~$ sudo apt update && sudo apt install -y systemd-genie
取得:1 https://arkane-systems.github.io/wsl-transdebian/apt focal InRelease [3,215 B]
ヒット:2 http://archive.ubuntu.com/ubuntu focal InRelease
取得:3 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]
取得:4 https://arkane-systems.github.io/wsl-transdebian/apt focal/main Sources [1,615 B]

- 省略 -

python3.8-dev (3.8.10-0ubuntu1~20.04.2) を設定しています ...
systemd-genie (2.3) を設定しています ...
python3-dev (3.8.2-0ubuntu2) を設定しています ...
man-db (2.9.1-1) のトリガを処理しています ...
dbus (1.12.16-2ubuntu2.1) のトリガを処理しています ...
libc-bin (2.31-0ubuntu9.7) のトリガを処理しています ...
fjij@STELLA:~$ 
```
### Genieの初期設定
WSLではサポートされていないサービスがあるため、Genieを実行するとサービス起動のタイアウト待ちとなってしまいます。追加設定や無効化を行います。

- iniファイルの編集とエラー回避操作を行います。
```terminal
fjij@STELLA:~$ sudo cp /etc/genie.ini /etc/genie.ini.bak
fjij@STELLA:~$ sudo sed -i 's/systemd-timeout=240/systemd-timeout=30/g' /etc/genie.ini # タイムアウト値を30秒に設定
fjij@STELLA:~$ sudo sed -i 's/update-hostname=true/update-hostname=false/g' /etc/genie.ini # ホスト名表示に-wslを追加されないように設定
fjij@STELLA:~$ sudo e2label $(df / | awk '/\//{print $1}') cloudimg-rootfs # cloudimg-rootfsエラーの設定
fjij@STELLA:~$ sudo ssh-keygen -A # sshdエラー回避の設定
ssh-keygen: generating new host keys: DSA
fjij@STELLA:~$
```

- 一度Genieを起動します。初回起動はエラーが発生しますが問題ありません。
```terminal
fjij@STELLA:~$ genie -s
genie: WARNING: systemd default target is default.target; targets other than multi-user.target may not work
genie: WARNING: if you wish to use a different target, this warning can be disabled in the config file
genie: WARNING: if you experience problems, please change the target to multi-user.target
Waiting for systemd....!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
genie: systemd did not enter running state (degraded) after 30 seconds
genie: this may be due to a problem with your systemd configuration
genie: information on problematic units is available at https://github.com/arkane-systems/genie/wiki/Systemd-units-known-to-be-problematic-under-WSL
genie: a list of failed units follows:

  UNIT              LOAD   ACTIVE SUB    DESCRIPTION
● multipathd.socket loaded failed failed multipathd control socket

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

1 loaded units listed.
genie: WARNING: systemd is in degraded state, issues may occur!
fjij@STELLA:~$
```

- サービス停止は ```systemctl ``` コマンドで行います。
```terminal
fjij@STELLA:~$ sudo systemctl disable getty@tty1
Removed /etc/systemd/system/getty.target.wants/getty@tty1.service.
fjij@STELLA:~$ sudo systemctl disable multipathd.socket
Removed /etc/systemd/system/sockets.target.wants/multipathd.socket.
fjij@STELLA:~$
```

## Dockerが動くようにする
```systemctl``` コマンドを利用するので、Genieを起動した状態で行います。起動していない場合は ```genie -s``` で起動してください。

### Docker Engineのインストール
- Dockerのリポジトリを追加します。
```terminal
fjij@STELLA:~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK
fjij@STELLA:~$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu  $(lsb_release -cs) stable"
取得:1 https://download.docker.com/linux/ubuntu focal InRelease [57.7 kB]
ヒット:2 https://arkane-systems.github.io/wsl-transdebian/apt focal InRelease
取得:3 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages [15.5 kB]

- 省略

409 kB を 2秒 で取得しました (252 kB/s)
パッケージリストを読み込んでいます... 完了
fjij@STELLA:~$
```
- インストールします。
```terminal
fjij@STELLA:~$ sudo apt update && sudo apt -y install docker-ce
ヒット:1 https://arkane-systems.github.io/wsl-transdebian/apt focal InRelease
ヒット:2 https://download.docker.com/linux/ubuntu focal InRelease
ヒット:3 http://security.ubuntu.com/ubuntu focal-security InRelease

- 省略 -

Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /lib/systemd/system/docker.service.
Created symlink /etc/systemd/system/sockets.target.wants/docker.socket → /lib/systemd/system/docker.socket.
man-db (2.9.1-1) のトリガを処理しています ...
systemd (245.4-4ubuntu3.15) のトリガを処理しています ...
fjij@STELLA:~$
```
- sudo無しでdockerコマンドを使えるようにユーザー設定を行い、併せて自動起動の設定を行います。
```terminal
fjij@STELLA:~$ sudo usermod -aG docker $USER
fjij@STELLA:~$ sudo systemctl start docker
fjij@STELLA:~$ sudo systemctl enable docker
Synchronizing state of docker.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable docker
fjij@STELLA:~$
```

### Composeのインストール
Dockerの利用にはComposeも導入しておくのが便利です。以前は```docker-compose```という独立したコマンドでしたが、現在はdockerのプラグインの1つとなっています。
(参照: https://docs.docker.com/compose/cli-command/#install-on-linux)

- インストールします。最新バージョンは[リリースページ](https://github.com/docker/compose/releases)で確認できます。
```terminal
fjij@STELLA:~$ sudo mkdir -p /usr/local/lib/docker/cli-plugins
fjij@STELLA:~$ sudo curl -sSL https://github.com/docker/compose/releases/download/v2.3.4/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose
fjij@STELLA:~$ sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
fjij@STELLA:~$
```

### Dockerの動作確認

- ```usermod```を実行したので、一度Genieを再起動します。
```terminal
fjij@STELLA:~$ exit
ログアウト
fjij@STELLA:~$ genie -s
fjij@STELLA:~$
```
- dockerのチュートリアルサンプルを実行します。
```terminal
fjij@STELLA:~$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:bfea6278a0a267fad2634554f4f0c6f31981eea41c553fdf5a83e95a41d40c38
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

fjij@STELLA:~$
```
- Composeの動作を確認します。
```terminal
fjij@STELLA:~$ docker compose version
Docker Compose version v2.3.4
fjij@STELLA:~$
```

## Window Terminalから開けるようにする

Genieを利用するには、.bashrcなどで設定する、タスクスケジューラでPC起動時に設定するなどの方法がありますが、今回はWindow TerminalからGenieのシェルを起動する方法をとります。

- Window Terminalの **メニュー** > **設定** から **新しいプロファイルを追加します** を選択します。
- Ubuntu-20.04をチェックして、**複製** を選択します。
 
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606374/cba1b8fc-cc96-24ab-5ad9-2c63a1cb5f49.png" width="75%">

- 名前を ```Ubuntu-20.04``` 、コマンドラインを ```wsl.exe -d Ubuntu-20.04 -- genie -s``` に変更して **保存** を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606374/02b77480-4ec7-5896-05d6-d841e42df5ad.png" width="75%">

これで、次回からWindows TerminalでUbuntuが起動できるようになります。

([その3](https://qiita.com/fjij/items/db7321f5ea61dcfb9907)へ続く)

# Tips
## 初回ログイン時のWARNINGについて
systemd のデフォルトターゲットは ```default.target (=graphical.target)``` になります。
GUIなどはインストールされていないので警告が表示されますが、ターゲットは systemctl コマンドで変更できます。
```terminal
fjij@STELLA:~$ sudo systemctl set-default multi-user.target # multi-user.targetへ変更
Created symlink /etc/systemd/system/default.target → /lib/systemd/system/multi-user.target.
fjij@STELLA:~$ sudo systemctl set-default graphical.target # graphical.targetへ変更
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target → /lib/systemd/system/graphical.target.
fjij@STELLA:~$
```

## shutdown時の動きについて
Genieを導入すると、shutdownやrebootコマンドが利用できるようになります。ただ、私の環境では以下のエラーが出て、ホスト名の-wslが増殖するため、Genieの接尾語を追加しない設定に変更しています。
```terminal
umount: /proc/sys/fs/binfmt_misc: not mounted.
genie: failed to unmount binfmt_misc filesystem; attempting to continue
```
このような場合、PowerShellからwslを再起動することで正常な状態に戻すことができます。
```powershell
PS C:\Users\fjij> wsl --shutdown
```

## Genie無しで動かしたい場合
Windows Terminalの設定に追加した ```-- genie -s``` を削除してください。Ubuntuをリセットして初期状態に戻した際、変更を忘れるとUbuntuを起動できなくなります。