WSL2時代のDocker開発スタイル
PROBLEM
- あたらしくでたWSL2によって以前書いた記事からだいぶ状況が変わった
- 主な変更点
- WSLのアーキテクチャが2種類になり、WSLはその2つのアーキテクチャを管理する機能に変わった
- WSL1 Windows Subsystem for Linux上のLinux (LXCore/Lxss)
- WSL2 軽量Hyper-V上のLinux (Linux Kernel)
- /procや/sysなどの特殊ファイルもふくめた共有プロトコル「9P」が実装された
- Win32側の9Pクライアント
9prdr.sys - WSL側の9Pクライアント
/init
- Win32側の9Pクライアント
- WSLのアーキテクチャが2種類になり、WSLはその2つのアーキテクチャを管理する機能に変わった
- 主な変更点
-
SOLUTION
というわけで、前記事で掲げていた目標「WSLでDockerをつかったWebアプリケーション開発ができるかどうか」について再確認します。
対象環境
- Windows 10 Pro Version 1903 OS Build 18922.1000
- Windows Terminal (Preview) Version 0.2.1715.0
- WSL2
- Ubuntu Version 1804.2019.5210 (Linux 4.19.43-microsoft-standard)
- Docker version 19.03.0-rc3, build 27fcb77
- WSL1
- Ubuntu 18.04 LTS Version 1804.2019.522.0 (Linux 4.4.0-18922-Microsoft)
Windowsの開発環境を構築する
まず、Windowsの開発環境の構築ですが、既知の情報をふまえつつTIPSを順次紹介します。
WSLのインストール
WSLのパッケージ管理は下記2つを押さえておけば問題ないでしょう。
-
asdf/anyenv
- プログラミング言語をバージョンごとにわけて使いたい場合はこちらをつかいましょう
- 関数言語界隈ではasdfが主流になってきてるようです。
-
nix
- Haskellのようにasdf/anyenvでインストールできない、あるいは、扱われいないパッケージはnixをつかいましょう
- また、aptのバージョンが古すぎるパッケージもnixが最適です
ターミナルのインストール
WSLttyはWSL2に対応しておらずConEmuは描画がくずれやすいため、デフォルトのターミナルかWindows Terminalが選択肢となります。
Windows TerminalとConEmuとの比較
| - | Windows Terminal | ConEmu |
|---|---|---|
| 透過対象 | backgroundImage | ConEmu自体 |
| キーバインド制約 | Alt+Shiftが効かない | 特になし |
| WSL2の描画 | 特になし | くずれる |
| 管理者権限で実行 | 初回のみ | タスク実行ごと |
Dockerのインストール
WSL1ではDockerデーモンがつかえないのでWSL2でDockerをつかうようにしましょう。Docker CEをインストールします。
どうしてもWSL1でということであれば、Win32 (WSL1からみるとdrvfs) 側でDocker For Windowsを用意します。インストールはDockerのダウンロードページから手順通りおこないます。 構成等は前回の記事を参照ください。
さて、WSL2からDockerはどの程度つかえるのか
WSL2は軽量Hyper-V上にLinuxコンテナを動かしているので、基本Hyper-Vと同様にDockerをつかうことができます。
ただし、WSL1と違いlocalhostにWSL2がバインドできません。 また、WSL1と同様にWin32・WSL間でのファイルの読み書きにパフォーマンスの差が大きく出ています。
ひとつずつ解決方法を見ていきましょう。
1. WSL1と違いlocalhostにWSL2がバインドできません
WSL2がつかっているVirtual Switchはinternal onlyのため、Win32側からlocalhostをつかってWSL2にアクセスすることができません。現在対応中のようです。
対処方法は2つあります。
a. WSL1をつかう
これが一番楽ですが、WSL1は次項であげるパフォーマンス上の欠点があるので、Web系フロントエンド開発におけるライブリローディング機能をつかうケースに限定するといいでしょう。
b. Hostsファイルをつかう
Win32のHostsファイルでWSL2のeth0インターフェイスのIPアドレスに適当なホスト名を割り当てます(ポートごとにホストを振り分けたい場合はWSL2側にProxyを用意するといいでしょう)。
# C:\Windows\System32\drivers\etc\hosts
172.17.72.217 dashboard.local.me
WSL2のIPアドレスはコンテナを立ち上げるごとに変わるので、下記のようなコマンドレットをWin32側のPowerShell $PROFILEに用意しておくといいでしょう。WSL2だけで完結したい方はシェル上から powershell.exe -Command 'Sync-HostsToWslIp' と打つだけです。
# $PROFILE
function Sync-HostsToWslIp {
$hosts = "$env:SystemRoot\System32\drivers\etc\hosts";
$pattern = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}";
$wslip = bash.exe -c "ifconfig eth0 | grep 'inet '";
if ($wslip -match $pattern) {
$wslip = $matches[0];
} else {
echo "The Script Exited, the ip address of WSL 2 cannot be found";
exit;
}
cat $hosts | %{ $_ -match $pattern }
$rc = cat $hosts | %{ $_ -replace $matches[0], $wslip }
$rc | Out-File $hosts;
}
2. WSL1と同様にWin32・WSL間でのファイルの読み書きにパフォーマンスの差が大きく出ています
いろんな方がベンチマークを公開してるのでそれを参考にするといいでしょう。
Cf.
わたしは git status -sb をよくつかうので、そのコマンドで簡単なベンチマークとりました。
# WSLx
$ cd ~/nabinno.github.io
$ \time -f %e git status -sb
# Win32/WSLx
$ cd ~/nabinno.github.io
$ \time -f %e powershell.exe -Command 'git status -sb'
# Win32
PS> cd ~/nabinno.github.io
PS> (Measure-Command { git status -sb }).TotalMilliseconds / 1000 | %{ [math]::Round($_, 2) }
| Subject | WSL | Win32 |
|---|---|---|
| WSL1 | 0.47 | 0.09 |
| WSL2 | 0.00 | 0.61 |
| Win32/WSL1 | 2.66 | 1.91 |
| Win32/WSL2 | 2.81 | 1.79 |
| Win32 | 0.51 | 0.12 |
Docker以外でWSLの課題はないのか
デバイスへのアクセス
以前から要望があったものだと「デバイスアクセスができない」件があります。
9P導入前だとこれはElixirのIoTフレームワークNervesのように、WSL UtilitiesでWSLパスをWin32パスに変換してからWin32にあるデバイス関連ツールをつかうのが簡単な解決策でした。
$ fwup.exe -a -i $(wslpath -w -a _build/rpi0_dev/nerves/images/hello_nerves.fw) -t complete -d $(fwup.exe -D | sed 's/,.*//')
ただし9Pを導入したWindows 10 Version 1903以降は、WSL1もWSL2もともにWSLパスを変換せずにWin32にあるデバイス関連ツールをつかうことができます。
$ fwup.exe -a -i _build/rpi0_dev/nerves/images/hello_nerves.fw -t complete -d $(fwup.exe -D | sed 's/,.*//')
-
WRAPUP
わたしの観測範囲では課題はほぼ問題ない状態になっていました。
おすすめ開発環境は下記のとおり
| item | content |
|---|---|
| IDE | WSLx上のエディタ |
| Webフロントエンド開発 | WSL1 |
| Docker関連開発 | WSL2 |
| dotfiles | WSLx、Win32を共有管理 |
Win32側のIDEをつかっているユーザーはパフォーマンス上の不満がまだあるかもしれませんが、WSLでDockerをつかったWebアプリケーション開発は十分できる、と言えそうです。つまり、Linux・macOS・WindowsによるWebアプリケーション開発は十分共有できる、と。
いい時代になりました。
-
以上 ![]()