マイペースなRailsおじさん

Ruby、Ruby on Rails、オブジェクト指向設計を主なテーマとして扱います。だんだん大きくなっていくRuby on Rails製プロダクトのメンテナンス性を損なわない方法を考えたり考えなかったりしている人のブログです。

Docker ToolBoxのDocker環境をWindows 10 HomeのBash On Windowsから使う

結論

docker-machine.exe start default
docker.exe $(docker-machine.exe config default) run hello-world

はじめに

Windows 10 HomeでDocker Toolboxで入れたDockerをBash On Windowsを使う方法を説明します。 Docker for Windows + Bash on Windowsだったり、Dockerを入れたVM + Bash on Windowsとはちょっと違う環境の話です。 Docker for Windows使えればよかったんですけどねぇ。

注意

本ページに登場するコマンドの.exeは省略しないでください。 省略すると、コマンドが見つからずエラーになるか、Linux Subsystemの方にインストールされたコマンドが実行されてしまいます。

環境

Windows 10 HomeではDocker for Windowsが利用できないので、Docker Toolboxを使います。Docker ToolboxとBash on Windowsはインストール済みという前提で説明していきます。

BoWからdocker.exeはうまくいかない

BoWからDocker Toolboxでインストールされたdocker.exeを実行すると次のようなエラーになります。

$ docker.exe ps
error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.31/containers/json: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.

docker.exeはDockerのクライアントですから、docker daemonというdockerのコンテナを実際に動作させるサーバと接続しなければなりません。 BoWからdocker.exeを起動した場合、接続先の設定がされていないためエラーになります。 Docker Quick Start Terminalでは起動時にこの設定を行ってくれるようです。以下では、Docker Quick Start Terminalに頼らず接続設定を行う方法を説明していきます。

docker-machine.exeでdocker-daemonを起動する

Docker Toolboxで使えるようになるDocker daemonは、実はdocker-machineで作られたVM上にあるので、docker-machine.exeを使って確認できます。

$ docker-machine.exe ls
NAME      ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
default   -        virtualbox   Stopped                 Unknown

defaultという名前のdocker machine(docker daemonを動作させるVM)があるのがわかりますね。Docker Quick Start Terminalではこのdocker machineを利用しています。STATEがStoppedなので、まずは起動しましょう。私の環境では起動に3分くらいかかりました。

$ docker-machine.exe start default
Starting "default"...
(default) Check network to re-create if needed...
(default) Waiting for an IP...
Machine "default" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

Docker Quick Start Terminalは、起動時このdocker machineの立ち上げも自動で行っていたというわけです。

Dockerを使う

起動したdocker machineを介してdockerを操作するには、下記のコマンドを使います。

docker.exe $(docker-machine.exe config default) [dockerコマンド]

[dockerコマンド]にはrun mysqlpsなど、docker操作用のコマンドを入れてください。docker-machine.exe config defaultでdefault(Docker Machine)に接続するためのdocker.exeのためのオプションが生成されるので、これを評価したものを引数にしています。

では実行してみます。

$ docker.exe $(docker-machine.exe config default) run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
9bb5a5d4561a: Pulling fs layer
9bb5a5d4561a: Verifying Checksum
9bb5a5d4561a: Download complete
9bb5a5d4561a: Pull complete
Digest: sha256:f5233545e43561214ca4891fd1157e1c3c563316ed8e237750d59bde73361e77
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/engine/userguide/

BoWからDocker ToolboxでインストールしたDockerを操作することができました。

おまけ: もうちょっと楽にする

docker machineの起動と、docker操作用のコマンドにaliasを張っておきます。

alias dmsd='docker-machine start default'
alias docker='docker.exe $(docker-machine.exe config default)'

docker machineの起動は/etc/rc.localに書いておけばうまくいくでしょうか? すみません、試してないのでわかる方いらっしゃいましたらコメントか何かで教えてください😷

余談

Docker Toolboxのほうでは、おそらくdocker-machine.exe env default --shellで生成される設定スクリプトを起動時に実行して環境変数を設定しているのですが、これと同じ方法はBoWでは使えません。というのも、docker.exeはBoWで設定された環境変数を読んでくれないからです。 ならば、Windowsにインストールしたdocker.exeでなく、BoWにインストールしたdockerクライアントを実行すれば環境変数を読めるのでうまく動きそうです。結果は、これもダメでした。docker-machine.exe env default --shellで設定した環境変数では、pemファイルのパスがWindowsの形式(C:\foo\bar\的な)で設定されてしまい、BoWからはそのパスをたどれないからです。