Dockerはサーバー側のDockerデーモンとクライアント側のDocker CLIで構成されています。Windows上でDocker環境を構築する場合は、Docker Desktopなどを使用しますが、裏側でWSL2上のDockerデーモンをWindowsのDocker CLIから操作しています。
Docker CLIのバイナリは個別には公開されていないと思いますが、GitHubに公開されているソースから自前でビルドしてみました。
- Docker CLIはソースコードがGitHubで公開されている
- ビルドはとても簡単
- 使い所は難しい
ビルド
環境構築
Docker CLIのビルドにはDocker環境が必要です。(なのでLinux環境が必要です) 簡単にLinux環境が構築できるmultipassを使用しました。
multipassではDockerインストール済みの仮想環境をコマンド一つで構築できます。
multipass launch docker --name multipass-docker
仮想環境が作成できたらシェルでログインします。
multipass shell multipass-docker
ビルド手順
ソースの取得
git clone https://github.com/docker/cli.git
ビルド
cd cli
docker buildx bake --set binary.platform=windows/amd64
以上です。簡単ですね。build
ディレクトリにdocker-windows-amd64.exe
が生成されます。
platformを変更することで、arm64版バイナリ(windows/arm64
)やmac版バイナリ(darwin/amd64
、darwin/arm64
)も生成できるようです。
Windowsへバイナリのコピー
Linux環境からログアウトします。
exit
transfer
コマンドで仮想環境からホスト側へファイルをコピーします。
multipass transfer multipass-docker:/home/ubuntu/cli/build/docker-windows-amd64.exe .
使ってみる
作成したDocker CLIを使用してみます。
.\docker-windows-amd64.exe version
Client:
Version: 22.06.0-beta.0-195-g3dfef7691e.m
API version: 1.42
Go version: go1.19.2
Git commit: 3dfef7691e
Built: Fri Nov 4 04:23:20 2022
OS/Arch: windows/amd64
Context: default
error during connect: this error may indicate that the docker daemon is not running: Get "http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/version": open //./pipe/docker_engine: The system cannot find the file specified.
通信するDockerサーバー側が設定できていないためエラーになりました。
Dockerサーバー側の設定
multipassの環境をDockerサーバーとします。Docker CLIとDockerデーモンの通信にSSH接続を使用する方法を試しました。
認証鍵の作成 Linux側で鍵を生成します。
ssh-keygen -t rsa -b 4096
いくつか質問が表示されますが、全て未入力とします。
公開鍵の方をauthorized_keysに登録
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
秘密鍵をWindows側にコピー Linux環境を抜け、Windows上で実行します。
multipass transfer multipass-docker:/home/ubuntu/.ssh/id_rsa .
注記秘密鍵はユーザーフォルダ(C:\Users\xxx)配下に置くのが良いようです。
SSH接続情報を登録 SSH設定ファイル(
%USERPROFILE%\.ssh\config
)に以下の内容を記載します。Host multipass-docker
HostName 172.17.xxx.xxx
User ubuntu
IdentityFile ~/.ssh/id_rsa注記仮想環境のIPアドレスは
multipass info multipass-docker
で確認できます。
これでWindows環境からSSH接続ができるようになったと思います。パスワード無しでログインできることを確認してください。
ssh multipass-docker
Docker CLI側の設定
Docker CLIのグローバルオプションとして-H ホスト名
を渡すことで、接続サーバーを指定できます。
.\docker-windows-amd64.exe -H "ssh://multipass-docker" version
Client:
Version: 22.06.0-beta.0-195-g3dfef7691e.m
API version: 1.41 (downgraded from 1.42)
Go version: go1.19.2
Git commit: 3dfef7691e
Built: Fri Nov 4 04:23:20 2022
OS/Arch: windows/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 20.10.21
API version: 1.41 (minimum version 1.12)
Go version: go1.18.7
Git commit: 3056208
Built: Tue Oct 25 17:59:49 2022
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.9
GitCommit: 1c90a442489720eec95342e1789ee8a5e1b9536f
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0
無事、サーバー側に接続ができました。(OS/Arch
がlinux/amd64
になっているのでLinuxへ接続できていることが確認できると思います。)
常に-H
オプションを指定するのは大変なので、context
を登録します。
.\docker-windows-amd64.exe context create multipass-docker --docker "host=ssh://multipass-docker"
作成したcontextを使用するように設定します。
.\docker-windows-amd64.exe context use multipass-docker
これで常にmultipass-dockerをサーバーとして使用する用に設定ができました。
.\docker-windows-amd64.exe version
Client:
Version: 22.06.0-beta.0-195-g3dfef7691e.m
API version: 1.41 (downgraded from 1.42)
Go version: go1.19.2
Git commit: 3dfef7691e
Built: Fri Nov 4 04:23:20 2022
OS/Arch: windows/amd64
Context: multipass-docker
Server: Docker Engine - Community
Engine:
Version: 20.10.21
API version: 1.41 (minimum version 1.12)
Go version: go1.18.7
Git commit: 3056208
Built: Tue Oct 25 17:59:49 2022
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.9
GitCommit: 1c90a442489720eec95342e1789ee8a5e1b9536f
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0
docker run
も動作することを確認します。
.\docker-windows-amd64.exe run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:e18f0a777aefabe047a671ab3ec3eed05414477c951ab1a6f352a06974245fe7
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/
使った感想
- VolumeはLinux側のディレクトリがマウントされる
-v
オプションでコンテナにマウントできるディレクトリはDockerサーバー側(Linux側)のディレクトリになります。
- docker buildができない?
設定が不十分なのか、docker buildがエラーになります。
[+] Building 0.0s (0/0)
error: failed to get status: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing cannot connect to the Docker daemon. Is 'docker daemon' running on this host?: context canceled"
無理せず、Docker DesktopやRancher Desktopを使うのが良さそうです。