dat.blog
dat
dat
nxdataka

データ分析の世界に惹かれて30代で分析会社に転職して3年目です。数学・統計学・機械学習・プログラミングと色々苦しみ&楽しみながら勉強中。ブログは自然言語処理の話題が多めになりそう?

WSL2を使ってWindows HomeにDocker環境を構築

これは何?

WSL2を利用してWindows HomeでDockerを利用するまでの手順やTIPSをまとめたメモ。
何番、何十番煎じかのいわゆる「やってみた」記事だが、色々気になることを調べながら進めたので、補足とその他TIPSのほうが本編の記事になっている。

ちなみに、今更試したきっかけは、評判の悪いMay 2020 Updateを適用しなくてもWSL2が利用できるようになったため。

前提条件

  • 管理者権限
  • Windows 10 Home

    • WSL2利用のために、Windowsのバージョンを以下のいずれかにする

      • 2004(ビルド19041)以降
      • 1909(ビルド18363)以降
      • 1903(ビルド18362)以降

補足:windowsのバージョンの確認&更新方法

win+R(みたいなキーとR同時押しの意),winver,enterで確認可能。 winver winver

確認結果が上記前提条件のビルド以前であれば設定>更新とセキュリティ>Windows updateを確認。
追加の更新プログラムに「累積更新プログラム」が存在するはずなので、「今すぐダウンロードしてインストール」を実行。

補足:2004以降に更新(May 2020 Updateを適用)すべきか

WSL2がMay 2020 Update以前のバージョンで利用できるようにバックポートされたので、現時点(2020年9月)では、無理に2004に上げる(May Updateを適用する)必要はない。
ちなみに2004は当初から不具合がたくさんあり(こっちは解消されつつある)、かつ、Updateの度に致命的な不具合が発生しているっぽいので、自然にUpdateが降ってくるまで待つのが良さげだと思っている。

参考:
2004の当初不具合
「Windows 10 May 2020 Update」に関連する不具合のまとめ
2004のアップデート不具合一例
Windows 10 2004の累積更新でWSL2がクラッシュする問題
Windows 10に累積更新。ただし、2004では日本語IMEに不具合が発覚済み
WSL2のバックポート
「WSL 2」が「Windows 10 バージョン 1903/1909」でも利用可能に ~Microsoftが旧OSに移植

手順1.WSLの導入

「Linux用Windowsサブシステム」の有効化

コマンドプロンプトやPowerShellを管理者として実行(win+R,cmdまたはpowershell,ctrl+shift+enter)し、下記コマンドを実行

cmd(admin)
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

※または、win,Windowsの機能の有効化または無効化を検索、選択し、「Linux用Windowsサブシステム」にチェックを入れてOKボタンを押下 forWSL

Linux(WSL)のインストール

Microsoft Store(win,storeで検索)から使いたいLinuxディストリビューション(例:Ubuntu)を検索し入手。 store ※MicrosoftのアカウントでStoreにログインする必要があるかも。

補足:Microsoft StoreにUbuntuが何種類もある。どれを選ぶべきか?

お好きなものをどうぞ。
余裕があれば、複数種入れて、ディストリビューション毎にこっちはWSL専用/WSL2専用と使い分けてもいいかも。

参考:
ストアにある3つの「Ubuntu」の違いは?

WSL初期設定

WSL(入手したLinuxディストリビューション)を初回起動し、任意のユーザーアカウントとパスワードを設定する。
※WSLの起動はWindowsのスタートメニューから入手したディストリビューションを探し、クリックで実行するか、コマンドプロンプト等からwslbashコマンドを実行する。

パッケージ更新

WSL側(Linux側)でパッケージをアップグレードする。WSL側で下記コマンドを実行。

WSL
sudo apt update && sudo apt upgrade

※パスワードの入力が求められるので、前段の初期設定で設定したものを入力する。

また、インストールされているgitが古いバージョンなので、気になる人は更新するとよい。

WSL
sudo apt install git

補足:複数ディストリビューションを入手している場合のWSL起動について

デフォルトの(wslコマンドで起動する)ディストリビューションはwsl -lで確認可能。
デフォルトを変更したければ、wsl -s <ディストリビューション名>で。

また、WindowsTerminalを使うと入手済みの複数ディストリビューションから選択して起動するのが楽になるほか、複窓起動をタブ/ペイン分割で行えるなど、WSLを使いやすくする機能が色々そろっているのでオススメ。

参考:
Windows Terminalとは
このブログでも、以前導入方法を解説済み
快適にWindows Terminalを使うための最小限の設定と使い方

手順2.WSLからWSL2への移行

「仮想マシン プラットフォーム」の有効化

コマンドプロンプトやPowerShellを管理者として実行(win+R,cmdまたはpowershell,,ctrl+shift+enter)し、下記コマンドを実行

cmd(admin)
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

※または、win,Windowsの機能の有効化または無効化を検索、選択し、「仮想マシン プラットフォーム」にチェックを入れてOKボタンを押下 forWSL2

Linuxカーネルの更新

下記リンクより、「Linuxカーネル更新プログラムパッケージ」をダウンロード&インストール。
https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel

WSLのバージョン変更

コマンドプロンプト等からwsl -l -vでインストール済みのディストリビューションおよびWSLのバージョンを確認。
表示例:

cmd
>wsl -l -v
  NAME            STATE           VERSION
* Ubuntu          Stopped         1
  Ubuntu-18.04    Stopped         1

続いて、下記コマンドでWSLのバージョンを2に変更する。

cmd
wsl --set-version <変更したいディストリビューション名> 2
# 例
# wsl --set-version ubuntu-18.04 2

変換が完了したら、再度wsl -l -vを実行してバージョンを確認。

表示例:

cmd
>wsl -l -v
  NAME            STATE           VERSION
* Ubuntu          Stopped         1
  Ubuntu-18.04    Stopped         2

ちなみにWSL2からWSLに戻したくなったらwsl --set-version <変更したいディストリビューション名> 1とすればよい。

補足:WSLからWSL2への変換が完了しない

まれに、wsl --set-version <変更したいディストリビューション名> 2を実行する段階で、「必要な機能がインストールされていないため、操作を開始できませんでした」とエラーが出る模様。
その場合は、この記事の手順で対処可能。

補足:新規入手するディストリビューションをWSL2で取得する

以下コマンドを実行すると、以後、Microsoft Storeから入手するディストリビューションはWSL2の状態でインストールされる。

cmd
wsl --set-default-version 2

手順3.Docker導入

Docker Desktopをインストール

以下リンクより、Docker Desktopのインストラーをダウンロードし、実行する。
https://www.docker.com/products/docker-desktop

入手するのは、Windows版のDocker Desktopである点に留意。
また、Stable(安定版)かEdge(最新版)の選択だが、現時点(2002年9月)では、Windowsのバージョンが2004の場合のみ、Stableを選択可能。1909/1903ならEdgeを選ぶ必要がある

インストーラーの画面で「Install required Windows components for WSL」にチェックが入っているかを確認して続ける。(デフォルトではチェックが入っている) irwsl

インストールが完了すると「Close and logout」(または、「Close and restart」)が表示されるので、押下して再度ログイン(または再起動)。 logout

ログイン後、Docker Desktopが自動起動される。 DDrunning ※自動起動しない場合はおそらく管理者権限が付与されていないアカウントでログインしている。スタートメニューからDocker Desktopを右クリックし、管理者権限で実行すれば起動できると思われる。

「Get started with Docker in a few easy steps!」の文字とともにチュートリアルが表示される。
いったん無視して※歯車マークをクリックし、設定を表示。
※チュートリアルは適宜進めてもよいし、スキップしてもよい。自分はスキップした。

General > Use the WSL2 based engineにチェックが入っていることを確認。 setting1 続いて、Resource > WSL INTEGRATIONを確認。
「Enable integration with my default WSL distro」にチェックを入れるか、「Enable integration with additional distros」にて、Dockerのバックエンドとして使用したいディストリビューションにチェックを入れ、Apply & Restartをクリックして設定を反映する。 setting2

補足:DockerをLinux版で入れるか、Docker DesktopのWindows版を入れるか

今回はDocker DesktopのWindows版を入れた(Docker DesktopアプリのバックエンドでWSL2を使わせている)が、WSL2側に直接Linux版のDockerを入れて直接操作することもできるらしい。(試してない)
慣れている人ならこの方法でもよいかもしれないが、今はもうDocker Desktopアプリ側で対応してくれてるので、無理にこの方法を取らなくても良さそう。

以下Ubuntuでのインストール用のコマンド。

WSL2
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
# 以下1行は、非root環境でDockerを使うためのユーザー追加
$ sudo usermod -aG docker your-user

docker-composeも使うなら以下も。

WSL2
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.27.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

参照:
WSL 2 で Docker を使うパターン
Install Docker Engine on Ubuntu
Install Docker Compose

補足:StableかEdgeか

インストール時点で、1909/1903でもStableを利用できるか気になるなら、リリースノートを確認するのが確実。
1909/1903でもWSL2が使えるようなったが、その変更にDocker Desktop側が追従したのはバージョン「2.3.5.0」。
現時点(2020年9月)では、このバージョンの変更はStableには取り込まれていないため、May Update適用前ならEdgeを選ぶことになる。

参考:
「WSL 2」の旧OSバックポートに対応した「Docker Desktop Community 2.3.5.0」が公開

Docker動作確認

Docker Desktopを起動した状態で、いくつかコマンドを試してみる。
まずは、コマンドプロンプト等、Windows側からwsl -l -vを実行すると以下のような表示に変わっている。

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

Linuxディストリビューションと並んでdocker-desktop(とdocker-desktop-data)が表示されており、前述の設定でチェックをしたWSL2のディストリビューションがRunningになっていることが確認できる。
Docker DesktopのバックエンドでWSL2を使っているため、Docker Desktop起動中はバックエンドのWSL2も起動中になる模様。

続いて、docker versionでdockerのバージョンを確認する。
例として以下のような結果が得られる。

cmd
>docker version
Client: Docker Engine - Community
 Azure integration  0.1.14
 Version:           19.03.13-beta2
 API version:       1.40
 Go version:        go1.13.14
 Git commit:        ff3fbc9d55
 Built:             Mon Aug  3 15:00:38 2020
 OS/Arch:           windows/amd64 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          19.03.13-beta2
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.14
  Git commit:       ff3fbc9d55
  Built:            Mon Aug  3 15:06:50 2020
  OS/Arch:          linux/amd64  Experimental:     true
 containerd:
  Version:          v1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

※ここでエラー(error during connect)が出る場合は、下記の補足を参照。

ClientのOSがWindowsで、ServerのOSがlinuxになっていることが確認できる。

導入したのはWindows側のDocker Desktopだが、WSL側(先の設定でResourceとして選んだディストリビューション側)からでもdockerが呼び出せる。
実際に、WSL側からdocker versionすると以下のような表示が返ってくる。

WSL2
$ docker version
Client: Docker Engine - Community
 Azure integration  0.1.14
 Version:           19.03.13-beta2
 API version:       1.40
 Go version:        go1.13.14
 Git commit:        ff3fbc9d55
 Built:             Mon Aug  3 15:02:49 2020
 OS/Arch:           linux/amd64 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          19.03.13-beta2
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.14
  Git commit:       ff3fbc9d55
  Built:            Mon Aug  3 15:06:50 2020
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

こっちはClient側もLinuxになっている。

Windows側(コマンドプロンプト等)に戻り、確認を続ける。
docker-composeも入っているので、docker-compose versionでバージョン表示してみると、下記のようなちゃんと結果が返ってくる。

cmd
>docker-compose version
docker-compose version 1.27.0, build 980ec85b
docker-py version: 4.3.1
CPython version: 3.7.4
OpenSSL version: OpenSSL 1.1.1c  28 May 2019

最後に適当なイメージ、たとえばおなじみのhello-worldで動作確認する。
docker run hello-worldを実行。
pullrunとしなくても、ローカルにrunするイメージが存在しなかったら自動でpullしてくれるのでrunだけでいい。

cmd
>docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:4cf9c47f86df71d48364001ede3a4fcd85ae80ce02ebad74156906caff5378bc
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/

「Hello from Docker!~」が表示されたのでイメージのpull、およびrunに成功したことがわかる。
以上で、導入および、確認は完了とした。

補足:「error during connect」エラーが出る

以前、Docker Toolbox使っていた場合、このエラーに遭遇する可能性がある。
以下の、使わなくなったDocker Toolbox関係の環境変数を削除することで正常に起動できるようになる。

  • DOCKER_TLS_VERIFY
  • DOCKER_CERT_PATH
  • DOCKER_HOST
  • DOCKER_TOOLBOX_INSTALL_PATH

参考: Windows 10 Home で Docker Tool Box から Docker Desktop (with WLS2) に移行した
error during connect Get https://192.168.99.100:2376/v1.38/containers/json

その他TIPS

以下、その他で調べた補足情報や、知ってへぇ~っとなった情報などを羅列した。

エクスプローラーで(Windowsから)WSL側のファイルにアクセスしたい

エクスプローラー(win+E)のアドレスバーに\\wsl$\(Windows側なので、見た目上は¥¥wsl$¥の入力になる)と入力することでWSL側のファイルにアクセス可能。 exploer ※ここで見えないディストリビューションがある場合、それを起動していないだけ。

WSL側のコマンドラインにいるとき、カレントディレクトリをエクスプローラーで開きたいな、と思ったら、explorer.exe .とすればよい。
※explore.exeにカレントディレクトリ(.)を渡してやる形。

将来的にはエクスプローラーのサイドバーにペンギンアイコンが表示され、クリックだけで\\wsl$\が開くようになるのでもっと簡単になる模様。
さらに将来的には、WSL側にWindowsで読めないファイル形式の物理ディスクをマウントしてWSL経由で読みこむ、みたいなこともできるようになるらしい。

※ちなみにWSL側→Windows側のファイルにアクセスは、/mnt/ドライブ名にWindows側のディレクトリがマウントされているので、とくに意識せずともアクセスできる。

参考:
Linuxとの相互運用の改善 ~WSL、コンソール、エクスプローラー
Windows 10のファイルエクスプローラがWSL機能を統合。Linuxを示すペンギンアイコンが登場
Windowsで読めないext4ファイルシステムを「WSL 2」経由でマウント~ Dev版「Windows 10」Build 20211が公開

Dockerを使わない場合の開発は、WSLとWSL2どっちを使えばいい?

基本はWSL2で大丈夫。
ただし、OSファイルシステム間でのパフォーマンスはWSLがWSL2に勝るため、以下のようなケースはWSLのほうがパフォーマンスは高くなるとのこと。

  • プロジェクトファイルをWindowsファイルシステムに格納する必要がある。

    • ⇨つまり、ソースコードをWindows側(WSL側から見て/mnt/ドライブ名以下)に置くならWSLのほうがよい。逆に言えば、WSL2で開発するときは、ソースコード等はLinux側のディレクトリに置くと良い。
  • 同じファイルに対してWindowsとLinuxの両方のツールを使用したクロスコンパイルを必要とするプロジェクト。

参考:
例外的に WSL 2 ではなく WSL 1 を使用する場合

Docker idを取得(Docker hubにユーザー登録)すべきか

ユーザー登録しなくてもdocker pull(hubからのイメージ取得)はできる。個人利用なら、pushしたくなったらユーザー登録する、くらいの感覚で良さげ。
一応、匿名(ログインなし)だと、無料ユーザーに登録してログインしているとき場合と比べて、pull回数のレートリミットが低い※というデメリットはある。あるが、個人利用なら気にするほどでもない。
※匿名:6時間あたり100回まで、無料ユーザー(登録済み):6時間あたり200回まで

参考:
Docker Hubがコンテナイメージの保存期間に加えてPull回数にも上限を設定すると発表

WSL環境/コンテナー環境に入って開発するには?

VSCodeと、その拡張機能の「Remote Development※」を使うと簡単。
※ 以下3つの拡張機能のセット

拡張機能を入れて、コマンドパレット(ctrl+shift+p)や左下の><みたいなマークをクリックし、Remote-hoge系のメニューを実行するだけ。 vscode-remote

参考:
Developing inside a Container
「Visual Studio Code」で「WSL 2」上のリモートコンテナを使用するには、Microsoftが解説

WSL側で立ち上げたネットワークアプリにアクセスしたい

たとえばWSL側やDockerのコンテナー内でDjangoの開発環境を構築し、python manage.py runserverした場合、アプリにどうアクセスすればいいか問題。
WSLでもWSL2でもDocker内のコンテナーでも、Windows側からlocalhostにアクセスすればOK。
例に上げたDjangoの場合、デフォルトだと8000番ポートなので、Windows側のブラウザからlocalhost:8000にアクセスすればよい。
ポートフォワーディングしたりしなくていいのでとても楽。

参考:
ネットワーク アプリケーションへのアクセス
「WSL 2」最大の課題であった“localhost”問題が解決

VMとWSL2を併用できないって聞いたけど?

どうやら現時点(2020年9月)ではできるようになったっぽい。(試してない)

参考:
VMWareとWSL2が共存可能になっていた話
Can I use VirtualBox alongside Docker Desktop?

nvidia-docker(NVIDIA Container Toolkit)やNGCコンテナーを実行すれば、Deep Learning用の環境構築ができる?

現時点(2020年9月)で、通常のWindowsを使っている状態ではWSL2がGPUを認識しない(CUDAが使えない)ので無理。
Windowsのインサイダープログラムに登録し、Windows 10のプレビュー版を取得すればできるっちゃできる、という段階。

参考:
WSL 2 の GPU にはアクセスできますか? ハードウェア サポートを強化する予定はありますか?
待ってました CUDA on WSL2

野良のDockerイメージ使っても良い?

なんでもかんでも利用すると危ないこともあるみたい。
Official Imageかどうか確認したり、Dockerファイルを確認したりしましょうとのこと。

参考:
Docker Hubのイメージを利用する時の注意点と判断材料
Dockerは危険という誤解と、本当に注意すべき点

WSL環境を初期化したい

Windowsの設定>アプリと機能>初期化したいディストリビューションの詳細オプション>リセットで初期化可能。 WSLreset

参考:
Windows 10のWSL環境を初期化してクリーンな状態に戻す

WSLでrm - rf /してもいい?

絶対だめ。Windows側も壊れるらしい。そういうのはVMで実験しましょう。

参考:
Windows 10 WSLで『rm -rf /』を実行

公式資料へのリンク