もろもろの事情でDocker Desktopを使いたくなくなったため、Docker Desktop for Windows無しに、似たようなDocker環境をWindowsに構築する手順を確認しました。
(2021-09-05追記) 私はWSL2をDocker以外の目的で使用していないので気にしませんが、他の目的にも使っているという方は 「(おまけ) Docker用のディストリビューションを分ける」 を先に参照したほうが良いかもしれません。
(2022-01-29追記) Visual Studio Code (VSCode) に、WSL環境内の docker
コマンドを直接使用できるオプションが追加されました。この機能を有効にすると、VSCodeからコンテナを使用するために一旦WSLに接続したり、Windows側にDocker CLIをインストールしたり、というステップが不要になります。詳細は (おまけ2) VSCodeからWSL上のdockerコマンドを直接使用する を参照してください。
1. Dockerのインストール
WSL2のディストリビューション上にDockerをインストールします。
WSL2にUbuntu 20.04のディストリビューションを導入
以下の「手動インストールの手順」そのままです。
ディストリビューションとして Ubuntu 20.04 LTS
をインストールします。
以降の手順は、特に記載がない限りこのWSLディストリビューション内で行います。
Ubuntu上にDocker Engineをインストール
以下の Install using the repository
の手順そのままです。
書かれているコマンドを上から実行していけばOKですが、以下の部分は不要です。
-
Install Docker Engine
の2. To install a specific version of Docker Engine, ...
の部分(最新以外のバージョンをインストールしたい場合の手順なので) - 最後の
Verify that Docker Engine is installed correctly ...
の部分(この時点ではまだ動きません)
一般ユーザーへの権限付与
WSLで使う一般ユーザーから docker
コマンドが使用できるようにするため、以下のコマンドでWSL用ユーザーを docker
グループに所属させます。
sudo usermod -aG docker $USER
Docker Daemonの起動・自動起動の設定
WSLにインストールした場合、Docker Daemon は自動的に起動しないので、以下のコマンドで手動起動します。
sudo /etc/init.d/docker start
また、WSLで使うユーザーの .bashrc
に以下を追記しておくと、ディストリビューションが再起動された後も、一度 wsl
コマンドで接続するだけで自動的に起動できます。
# Start dockerd
sudo /etc/init.d/docker start
このときパスワードを聞かれるのが煩わしい場合は、以下のコマンドを実行し、sudoers
ファイルを編集します。
sudo visudo
nanoエディタが起動するので、末尾に以下を追加した後、 Ctrl+X
-> Y
-> Enter
で保存・終了します。
%docker ALL=(ALL) NOPASSWD: /etc/init.d/docker
これにより、上記の起動コマンドを実行した場合だけはパスワードが不要になります。
動作確認
以下のように Hello World イメージを実行します。
docker run hello-world
Hello from Docker!
と表示されれば正しくインストールできています。
2. Docker Compose (v1) のインストール
Visual Studio Code の Remote Containers 拡張では docker-compose
コマンドも必要になるため1、インストールします。以下の Install Compose on Linux systems
の手順そのままです。
3. Dockerコマンドの利用
今後の docker
コマンドの実行は、 wsl
コマンドでいったんLinuxに入ってから行うようにします。
ただし、Docker Desktop for WindowsのようにWindowsのパスをそのまま使用はできないので、 -f C:\src\test\Dockerfile
のようにパスが出てくる個所は、 -f /mnt/c/src/test/Dockerfile
のようにLinux側からみたパスに置き換える必要があります。
追加情報
以下にあるようにバッチやPowerShellスクリプトを作成することで、Windowsから docker
コマンドをそのまま実行できるようにすることもできます。
ただし、上記のパスの問題や、 --mount
オプションのようなカンマ区切りパラメータの問題(PowerShellではエスケープが必要)もあり、バッチやPowerShellだけではDocker Desktopと全く同じ動作にするのは厳しそうです。
4. Visual Studio Code からの利用
(2022-01-29追記) Visual Studio Code v1.61から、この操作は不要になりました。詳細はおまけ2を参照ください。
Windowsから起動したVisual Studio Codeでは、Docker DesktopのようにRemote Containers拡張の機能をそのまま使用することはできません。
WSL内から
# カレントディレクトリを開く
code .
のようにVisual Studio Codeを起動し、WSLに接続された状態にする必要があります。
接続した後は、Docker Desktop の場合と同じように Open Folder in Container...
などのメニューが動作するようになります。
参考情報
5. ダッシュボードの代替
Docker DesktopのダッシュボードのようにGUIでのDocker環境管理を行いたい場合、Portainerを使用するのが簡単そうです。
インストール
以下のドキュメントページを
以下のようにたどり2、
Portainer Community Edition
Install Portainer CE
Set up a new Portainer Server installation
Docker Standalone
Install Portainer with Docker on WSL / Docker Desktop
Deployment
に記載のコマンドをWSL内から実行すればインストールは完了します。
起動したら、ブラウザから https://localhost:9443 にアクセスすると(ブラウザで自己署名証明書を受け入れる必要があります)、初期ユーザー登録画面になります。
適当なパスワードで Create user
ボタンで登録します。
次の画面では、local environment を使う方 (Get Started) を選択します。
local
がWSL内のDocker環境を表しています。
この中を確認すると、Docker Desktop のダッシュボードで提供されているようなコンテナ・イメージ・ボリュームなどの状況の確認や操作ができます。
ログの確認やコンソールアクセスなども可能です。
6. (おまけ) Docker用のディストリビューションを分ける
Ubuntuのディストリビューションを別の目的で使っていて、Docker環境に汚染されたくない、ディスク肥大化時に消したりできないのが気になる、という場合は、ディストリビューションを分けたほうが良いでしょう。
Docker用のディストリビューション作成
Windows上で、以下のようなコマンドで既存のディストリビューションをエクスポートします。 D:\backup\Ubuntu-20.04.tar
の部分はエクスポート先の任意のパスです。
wsl --export "Ubuntu-20.04" D:\backup\Ubuntu-20.04.tar
続けて、以下のようなコマンドで新しいディストリビューションとしてインポートします。
wsl --import docker D:\wsl\docker D:\backup\Ubuntu-20.04.tar
-
docker
の部分は、新しいディストリビューションに付ける名前です。 -
D:\wsl\docker
の部分は、新しいディストリビューション用のディスクイメージを配置したいフォルダです。 - 最後のパラメータは、さきほどエクスポートしたファイルのパスです。
この後、以下のコマンドでディストリビューションの一覧を確認すると、インポートしたものが追加されています。
wsl -l -v
結果:
NAME STATE VERSION
* Ubuntu-20.04 Stopped 2
docker Stopped 2
これで、以下のコマンドのように新しいディストリビューションを指定してWSLを起動できるようになります。
wsl -d docker
デフォルトユーザーの変更
インポートしたディストリビューションでは、上記のように起動するとデフォルトユーザーが root
になっているので、元のユーザーと同じになるようにします。
まず、以下のコマンドで元のディストリビューションのデフォルトユーザーのUIDを確認します(おそらく 1000
のはず)。
wsl -d "Ubuntu-20.04" id -u
確認できたら、PowerShellで以下のコマンドを実行します。
# さっき確認したUID
$uid = 1000
# 新しいディストリビューションの名前
$to_dist = 'docker'
Get-ItemProperty Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\*\ DistributionName | Where-Object -Property DistributionName -eq $to_dist | Set-ItemProperty -Name DefaultUid -Value $uid
これは、ディストリビューション用のレジストリの DefaultUid
を設定しているのと同じです。
この後は、以下のコマンドで一般ユーザーとして新しいディストリビューションを起動できます。
wsl -d docker
この後
あとは、このディストリビューションの中で 1~4 の手順と同様にDocker環境を構築していきます。
ディスクが肥大化したりしてディストリビューションを消したくなったら、以下のようなコマンドで消せます。
wsl --unregister docker
7. (おまけ2) VSCodeからWSL上のdockerコマンドを直接使用する
VSCodeのv1.61で、VSCodeがDocker機能を呼び出すときにWSL上の docker
コマンドを使うようにするオプションが追加されました。
VSCodeで以下のオプション "Execute In WSL" (remote.containers.executeInWSL
) にチェックを入れて有効にすると、
Open Folder in Container
などでRemote Containers拡張がdockerコマンドを実行するときに、自動的にWSL内のDockerで実行してくれるようになります。
これにより、WSL上だけにDockerをインストールすれば、(VSCodeの操作の上では)Docker Desktopと全く同じ感覚で Remote Containers を使えるようになりました。
ログを見ると、以下のようにwsl上でコマンドを実行し、パスも自動的に変換してくれています。
[55 ms] Remote-Containers 0.209.6 in VS Code 1.63.2 (899d46d82c4c95423fb7e10e68eba52050e30ba3).
[54 ms] Start: Resolving Remote
[60 ms] Start: Run: wsl -l -v
[91 ms] Start: Run: wsl -d docker -e wslpath -u d:\src\sandbox
[162 ms] Start: Run: wsl -d docker -e /bin/sh -c cd '/mnt/d/src/sandbox' && /bin/sh
VSCode v1.64 以降では、設定 "Execute In WSLDistro" (remote.containers.executeInWSLDistro
) で対象のディストリビューションを指定することもできます。何も指定しないとデフォルトのディストリビューションが使われます。
8. 結論
金を払えるなら払ったほうが楽ですね。