新しいことにはウェルカム

技術 | 電子工作 | ガジェット | ゲーム のメモ書き

WSL1でpuppeteerが動かなくなったのでWSL2に移行してみた話

今までWSL1を使っていて、WSL2が安定してきたら、そのうちWSL2を使ってみようかと考えていたのですが、今回必要に迫られてWSL2に移行しました。

WSL1からWSL2への移行と、それにまつわるDockerやX Serverの設定について、徒然なるままに書こうと思います。

移行のきっかけ

WSL1+VcXsrv(X Server)でpuppeteerを動かしていたのですが、Chromiumでエラーが出て動かなくなりました。

f:id:kwbtblog:20201202050845p:plain

Aw, Snap!
Something went wrong while displaying this webpage.
Error code: SIGABRT

調べたところ、明確な解は得られなかったのですが、どうもWSL1だとChromiumのウィンドウ表示には対応しきれないようでした…。

同じプログラムを、UbuntuをインストールしたPCで実行すると問題なく動いたので、ますますWSL1が怪しく、WSL2に移行すれば動くんじゃないかと、思い切って移行してみました。

結論から言うと、WSL2にするとpuppeteerが動くようになりました!!

WSL1からWSL2への移行手順

下記の記事を参考にしました。

既にWLS1を使っているので

  • Linuxカーネル更新プログラムのインストール
  • WSL2を既定のバージョンとして設定
    • wsl --set-default-version 2
  • UbuntuのバージョンをWSL2に設定
    • wsl -l -v:WSLディストリビューション一覧表示
    • wsl --set-version Ubuntu-18.04 2:WSL2に設定

のたったこれだけで、WSL1がWSL2に変更されました。

実行時間はかかりますが、想像以上に簡単でした。wsl --set-version Ubuntu-18.04 1で、WSL2からWSL1に戻すこともできます。

VcXsrv(X Server)の設定

下記の記事を参考にしました。

PowerShellでipconfigを実行すると、WSLという新しいIPアドレスが追加されていて、それがWSL2の仮想マシンのIPアドレスになっています。

PS > ipconfig

Windows IP 構成

イーサネット アダプター vEthernet (WSL):
   接続固有の DNS サフィックス . . . . .:
   IPv4 アドレス . . . . . . . . . . . .: 192.168.140.241
   サブネット マスク . . . . . . . . . .: 255.255.255.240
   デフォルト ゲートウェイ . . . . . . .:

WSL1はWindowsの一部なので、IPアドレスはWindowsと同じで、WSL1のDISPLAY環境変数に指定するIPアドレスはlocalhostでよかったのですが、WSL2は上記の仮想マシンのIPアドレスにする必要があります。

仮想マシンのIPアドレスは起動時に決まるので、ベタ書きではなく、下記の方法で動的にセットします。

export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0

そして、VcXsrvの起動時パラメータに--acを設定して起動すると、無事WSL2からVcXsrv(X server)を使ってウィンドウ表示ができるようになります。

f:id:kwbtblog:20201202050854p:plain

「Save configuration」で設定ファイルが保存できるので、次回からは設定ファイルをダブルクリックしてVcXsrvを起動するようにします。

Dockerの設定

今までは、WindowsにDocker Desktopをインストールして、WSL1から使っていました。

Docker DesktopをWSL2に対応するのは、下記の記事を参考にしました。

DockerをWSL2に移行する前に注意

  • 従来のDocker Desktopは、Hyper-VでDockerデーモンを実行するVMを立ち上げて、WSL1からそのVMにアクセスする形になっていました。Docker DesktopがWSL2に対応する際、一旦Docker Desktopが、以前のVMを削除してしまうので、Dockerでvolumeを使っていた場合、そのバックアップは移行の前に行っておく必要があります。

Docker DesktopをWSL2に移行する手順は下記のように簡単でした。

  • まずは、WSL2のDockerをアンインストールして、再度Dockerをインストール。
  • 続いて、Docker Desktopをアップデート。色々聞かれますが、後から設定可能なので適当に回答。

Docker Desktop設定

[Settings] - [General]

「Use then WSL 2 based engine」にチェックを入れると、Docker DesktopがWSL2対応になります。

f:id:kwbtblog:20201202050841p:plain

[Settings] - [Resources] - [WSL INTEGRATION]

上記だけだと、WSL2からDocker DesktopのDockerデーモンにアクセスできないので、「Enable integration with my default WSL distro」にチェックを入れて、どのWSL2のディストリビューションからDockerにアクセスするかのチェックを入れます。

f:id:kwbtblog:20201202050902p:plain

これで、WSL2からDocker Desktopにアクセスできるようになります。

WSL2はどこに作られるのか?

WSL2はHyper-VのVMかと思ったのですが、Hyper-Vマネージャーを見ても、それらしきVMが見当たりません。

f:id:kwbtblog:20201202050858p:plain

前述の通り、PowerShellでipconfigをすると、WSL2のIPアドレスが出てくるので、どこかにWSL2は存在してはいるのですが…。

WSL2は、Hyper-Vを利用しつつ、従来のHyper-VのVMとは別に、WSL2として独立して存在しているんですね。

Docker DesktopのDockerデーモンはどこに作られるのか?

PowerShellでwsl -l -vとすると、WSL2のディストリビューション一覧が見れるのですが、その中にdocker-desktopが出てきます。

PS > wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu-18.04           Running         2
  docker-desktop-data    Running         2
  docker-desktop         Running         2

なるほど~。Docker DesktopのDockerデーモンは、WSL2のディストリビューションの1つとして起動してるんですね。WSL2のUbuntu上で動いてるのかと思ってました。

WSL2のUbuntuとWSL2のDocker Desktopは別のVMなので、それらをつなぐ設定が、前述の[Settings]-[Resources]-[WSL INTEGRATION]ということなんですね。

従来のDocker Desktopデーモンを起動する

[Settings]-[General]で「Use the WSL 2 based engine」のチェックを外すと、従来の、Hyper-VのVMを用いた、Docker DesktopのDockerデーモンが立ち上がります。

f:id:kwbtblog:20201202051434p:plain

f:id:kwbtblog:20201202051439p:plain

互換性のために従来の選択肢も用意されているようです。

WSL2のUbuntuでDockerデーモンを起動する

WSL2はれっきとしたLinuxなので、それだけでもDockerデーモンが動きそう。実際試すとちゃんと動きました。

$ sudo dockerd &
$ docker ps
CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES

しかも、Ubuntuを一度閉じて、再度開いても、Dockerデーモンが残ってます。

$ ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root       899  0.0  0.0  67096  4168 ?        S    04:04   0:00 sudo dockerd
root       906  0.6  0.7 1566784 92612 ?       Sl   04:04   0:00 dockerd
root       918  0.7  0.4 1429072 52644 ?       Ssl  04:04   0:00 containerd --config /var/run/docker/containerd/containeroot...

WSL2は、ウィンドウを閉じても裏で動いているんですね。正にVMです。

となると、たまに再起動したくなるのですが、Linuxのシャットダウンコマンドが使えないので、wsl.exeからシャットダウンします。

wsl.exe --shutdown

Docker Desktopが無くても、WSL2だけで永続するDockerデーモンが立てられますね。Docker Desktopは容量食うし、開発用途だとDocker Desktopいらないかも。

というわけで、Docker Desktopをアンインストールして、WSL2のUbuntuでDockerデーモンを動かすことにしました。

WSL2のUbuntuでDockerデーモンを自動起動する

しかし、Dockerデーモンを自動実行しようとしても、WSL2ではsystemdが動かないため、そのままでは無理みたい…。

WSL2でsystemdが動くようにする方法はいつくかあるのですが、どれも面倒で定番的なのがなさげだったので、とりあえずDockerが必要な時に、手動で実行することにしました。どうしてもWSL2でsystemdが使いたくなったら、その時考えるとします。

WindowsからWSL2のファイルにアクセスする

WSL1の時は、//mnt/経由で、WSL1からWindowsのフォルダにアクセスしていたのですが、WSL2では、WSL2からWindowsのフォルダへのアクセスは遅いので推奨されていません。

とは言え、WSL2とWindowsでフォルダを共有できると便利なので、Windowsから\\wsl$経由でWSL2のフォルダにアクセスします。

f:id:kwbtblog:20201202050850p:plain

Windows Terminal

WSL2のドキュメントにWindows Terminalが出てきたので、ついでにインストールしました。シンプルで設定も楽そうです。

WSLのデフォルトのターミナルは、色が見づらかったのですが、Windows Terminalはカラーテーマを変えられるので見やすくなりますね。

あまり設定をいじるのは好きじゃないんですが、PowerShellの色はやっぱこれでしょ。ということで、PowerShellのテーマを「Campbell Powershell」にしておきました。

f:id:kwbtblog:20201202051645p:plain

感想など

以上で、もろもろのWSL1からWSL2への移行ができました。

最初、WSL2に移行するのはちょっと不安だったのですが、思った以上に簡単でした。WSL1の環境をそのままWSL2に移行できますし、使い心地もWSL1と変わりませんね。

むしろ、本物のLinuxなので、WSL2の方が安定している気がしないでもないです。少なくともpuppeteer、X server関連はWSL2の方が安定して使えます。

Dockerのビルドがイマイチのようでしたら、再度Docker Desktopを使うようにすればいいですしね。

今の所、WSL2に移行して良かったですし、満足しています!