Windows Subsystem for Linux (WSL)でDocker

4月あたりにWindows 10の新しいアップデートが出て、Windows Subsystem for Linux(WSL)の2が出れば状況はまた変わるのかもしれませんが、現行のWSL 1においてはUbuntu版Dockerを動かすのは容易なことではありません。

私のDockerの用途はというと、主にAWS LambdaとIBM Cloud Functionsで使うPythonモジュールをインストールしたパッケージを作るためにそれぞれの動作環境を再現できるDockerコンテナを動かすというものです。なので、実際のところdocker-composeを使うほどでもないし…。でも、Dockerが動かないと作業が進まないのもホントのところなのです。

WSL 1でのDockerはDocker Desktop for Windowsを使うのがベスト

WSL 1でという前提を入れれば、WSL上のUbuntuでDockerを使うにはWindows版のDocker(Docker Desktop for Windows)をUbuntu環境から操作するだけにとどめるのがベスト。無理やりUbuntu版のDockerを動かすこともできないこともないようなのですが、Dockerのバージョンアップを止めておかないとダメだとか、いつ動かなくなっても文句を言えない感じなので、まだ実験の域を出ません。

なので、ふつうにWindows版のDockerを動かして、それをUbuntuから操作できれば良いことにします。その方が安心感があります。

Windows側の設定

Docker Desktop for Windowsのインストールパッケージを起動するか、Chocolateyを使ってインストールした後、下記2つの設定を行います。

一つは、Docker Desktop for WindowsのSettings画面でGeneralタブのExpose daemon on tcp://localhost:2375 without TLSを有効にします。この設定で、Ubuntu側からWindows側のDockerを操作できるようになります。

もう一つは、Shared Drivesの設定です。私の環境ではDドライブで開発作業を進めているので、Dドライブを共有設定します。WindowsのログインをMicrosoftアカウントで行っている場合、共有設定時のIDとパスワードはMicrosoftアカウントになるので、注意しましょう。

Ubuntu側の設定

Ubuntu側にもDockerをインストールしておく必要があります。公式ドキュメントのDocker CEのインストール方法に沿って操作します。

もちろん、Ubuntu側のDockerデーモンは起動する必要はないので、下記のコマンドでデーモンを止めます。(WSLはデーモンを自動起動させる仕組みはないので、特に気にしなくても良いかもしれません。)

sudo service docker stop

次に、DockerのCLIがWindows側のDockerを操作できるようにするため、.bash_aliasesなどに下記の設定を行います。

export DOCKER_HOST=tcp://localhost:2375<br />
alias docker="DOCKER_HOST=${DOCKER_HOST} docker"<br />

これで、UbuntuからWindows側のDockerを操作できるようになりました。

WSL側のマウントディレクトリを変更する

ここまでの設定でUbuntuからDockerを一通り操作できるようになったのですが、一つ問題があります。それは、Dockerからローカル(Ubuntu)のファイルにアクセスできないことがあるのです。

例えば、IBM Cloud Functionsのパッケージ用にPythonモジュールをインストールする場合、下記のようなコマンドを実行します。

docker run --rm -v "$PWD:/tmp" ibmfunctions/action-python-v3.6
bash -c "cd /tmp && virtualenv virtualenv && source virtualenv/bin/activate && pip install -r requirements.txt"

ここで曲者はPWDです。私のようにD:\dev配下に開発用のファイルが存在している場合、例えばカレントディレクトリをD:\dev\test_projectにすると、WSL上のUbuntuでPWDすると、/mnt/d/dev/test_projectが得られることになります。(Ubutnu上のホームディレクトリから/mnt/d/devにシンボリックリンクを張った場合はまた別の結果が得られますので、注意してください。)

一方、Docker Desktop for WindowsはWindowsのHyper-V環境のLinuxで動作しており、共有設定したDドライブは/dにマウントされます。同じDドライブなんですが、WSL環境のUbuntuでは/mnt/d、Hyper-Vでは/dと相違が出ますから、上記のコマンドをそのまま動かすと、そんなディレクトリ(/mnt/d/dev/test_project)は知らんということでエラーになります。

ここで、コマンドを動かす際に$PWDではなく、d:\\dev\\test_projectのようにWindowsでのフルパスを書くという方法もあるのですが、WSL環境のUbuntu側でのマウント先を/mntではなく、/(ルート)にすることで、Hyper-V環境とマウント先を揃えるという方法もあります。

Ubuntu側で、/etc/wsl.confというファイルを作り、下記の設定を行います。

[automount]
root = "/"

後はWSLを再起動すれば、Windows側のドライブのマウント先が変わりますので、DドライブについてもHyper-V(Docker)と同じ/dになるわけです。これで、$PWDを含むコマンドを使ってもエラーは出なくなります。

とはいえWSL 2にも期待

これで、ひとまず私のSurface Pro LTE AdvancedでもDockerを使った作業が可能になりました。とはいえ、次のWindows 10のアップデートでWSL 2が提供されるようになると、DockerがWSL 2上で動くようになるとされていますので、今以上にDockerの運用が楽になるのではないかと思います。

ここ数年のMicrosoftははやりの技術をWindowsに導入して、開発者をMacから取り戻すことに必死ですから、その様子をウォッチするのはなかなか楽しい時間です。(待ち遠しいというか待ちくたびれることも多いのですが…。)WSL 2には期待しかないので、頑張ってほしいところですね。

この記事を書いた人

井上 研一

株式会社ビビンコ代表取締役、ITエンジニア/経済産業省推進資格ITコーディネータ。AI・IoTに強いITコーディネータとして活動。画像認識モデルを活用したアプリや、生成AIを業務に組み込むためのサービス「Gen2Go」の開発などを行っている。近著に「使ってわかった AWSのAI」、「ワトソンで体感する人工知能」。日本全国でセミナー・研修講師としての登壇も多数。