🐳

WindowsでもサクサクDocker (Docker on WSL2 without Docker Desktop)

2022/01/01に公開

目的

以前に WindowsでもサクサクDocker という記事を公開していますが、
そちらで利用しているDocker Desktopは2021年秋に一部条件を除いて有償化されました。
本手順ではDocker Desktopを使わずにWindows上で快適にDockerを使える環境を構築します。
なお、本手順で作ったDocker環境でGPUを使いたい場合は、以下の記事を参照してください。
https://zenn.dev/rhene/articles/docker-on-wsl2-with-gpu

また、本環境でVSCodeを使った開発環境を構築するためには、下記記事を参照してください。
https://zenn.dev/rhene/articles/docker-on-wsl2-for-vscode

内容

有償化されたDocker Desktopを使わずに、Windows上でDockerを使えるようにします。
大まかには下記手順になります。

  1. WSL2 のインストール
  2. Docker のインストール
  3. Docker Engineの起動

なお、下記環境で動作確認を行っています。

  • Windows 11 Pro 23H2 build:22631.3447
  • Windows 11 Pro 21H2 build:22000.376
  • Windows 10 Pro 21H2 build:19044.1415
  • Windows 10 Pro 21H1 build:19043.1415
  • Windows 10 Pro 20H2 build:19042.1415
  • Windows 10 Pro 2004 build:19041.1415

方法

WSL2 のインストール

Windows上で快適にDockerを使うためには WSL2 が必要になります。
Docker Desktopではバックエンドで利用する WSL2 のインストールをある程度お膳立てしてくれましたが、本手順では手動でインストールする必要があります。

WSL2のインストールに関しては別記事で公開していますので、下記記事を参照してください。
【Windows11 または Windows10 に WSL2 をインストールする】 - zenn.dev

なお、本手順ではディストリビューションとしてWSLのデフォルトである「Ubuntu」をインストールしていることを想定しています。

Dockerのインストール

DockerのインストールはWSLディストリビューション内で行います。
スタートメニューから「Ubuntu」を実行するか、PowerShellから「ubuntu」を実行した上で、下記コマンドを実行してください。

Dockerのインストール
# Dockerのインストール
sudo apt update
curl https://get.docker.com | sh

# docker-composeのインストール
# sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# sudo chmod +x /usr/local/bin/docker-compose
sudo apt install -y docker-compose

Docker Engineの起動

過去の方法

Dockerのインストールが完了したら、Docker Engineを起動してください。
これを行わないと docker コマンドは実行できません。

Docker Engineの起動
# Docker Engineの起動
sudo service docker start

# Docker Engineの起動確認
sudo service docker status

【実行結果 - 起動成功時】

実行結果 - 起動成功時
 * Docker is running

【実行結果 - 起動失敗時】

実行結果 - 起動失敗時
 * Docker is not running

Dockerの動作確認

Docker Engineを起動できたら Hello World を実行して、動作を確認してみましょう。
WSL上で以下のコマンドを実行します。

Hello Worldの実行
sudo docker run --rm hello-world

うまく動けば以下のように表示されるはずです。

Hello World 実行結果
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/

動作が確認できたら、不要なイメージは消しておきましょう。

Dockerイメージの削除
sudo docker rmi hello-world

以上でDocker Desktopのインストールは完了です。
それでは存分にDockerを楽しみましょう!!

sudo なしで docker コマンドを利用する

通常は docker コマンド実行には sudo コマンドを経由して管理者権限が必要になります。
この状態ですと VSCode の docker 拡張機能が権限不足でエラーになるため、下記コマンドを実行して、 sudo なしで docker コマンドを利用できるようにします。

WSL実行ユーザをdockerグループに追加
# sudo groupadd docker
sudo usermod -aG docker $USER
exit

# コンソールに入り直すと `sudo` が不要になる
docker images

【参考】

【Post-installation steps for Linux】 - Docker

トラブルシューティング

コンテナの起動に失敗する

コンテナ起動時に下記エラーが出て、コンテナの起動に失敗する

コンテナの起動失敗
docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
See 'docker run --help'.

【原因】 Docker Engineが動いていない

Docker Engineの起動確認
sudo service docker status
* Docker is not running

【ケース1】 単純にDocker Engineを起動していない
Docker Engineが起動していない場合、まずは sudo service docker start を実行してください。
その後、再度起動状態を確認してください。

引き続き Docker is not running が表示される場合は /var/log/docker.log を確認してください。

docker.log に下記のエラーが出ている場合

docker.logにエラーが出ている場合
sudo tail /var/log/docker.log

///var/run/docker/containerd/containerd.sock  <nil> 0 <nil>}. Err :connection error: desc = \"transport: Error while dialing dial unix:///var/run/docker/containerd/containerd.sock: timeout\". Reconnecting..." module=grpc
failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: iptables failed: iptables -t nat -N DOCKER: iptables v1.8.4 (legacy): can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
 (exit status 3)

【ケース2】 WSLのLinux Kernelのバージョンが古い
管理者権限で PowerShell を起動し、 wsl の更新と再起動を行う

Linux Kernelの更新
# Linux Kernelの更新
wsl --update
実行結果
更新をチェック中...
更新をダウンロード中...
更新をインストール中...
この変更は、次回の WSL 再起動時に有効になります。強制的に再起動するには、'wsl --shutdown' を実行してください。
カーネル バージョン: 5.10.60.1
wslの再起動
# wslの再起動
wsl --shutdown

【ケース3】 WSLのバージョンが「1」になっている

ディストリビューションの確認
# ディストリビューションの確認
wsl -l -v
実行結果
  NAME                   STATE           VERSION
* Ubuntu                 Stopped         1

上記のように VERSION1 になっている場合は、下記を実行してKernelのバージョンを 2 に設定してください。

Kernelバージョンの変更
# ディストリビューション「Ubuntu」のバージョンを「2」に設定する
wsl --set-version Ubuntu 2

# WSLのデフォルトバージョンを「2」に設定する
wsl --set-default-version 2

設定が完了したら wsl を再起動した上で、再度Docker Engineの起動を試みてください。

Discussion