Windows 上に構築した Docker Toolbox の Docker Machine を WSL 内の docker-compose
コマンドで操作できるようにします。
Windows に必要なものをインストール
Chocolatey でいろいろインストールします。別に Chocolatey じゃなくても良いです。
Docker Toolbox には VirtualBox が必要なのでインストールします。また、VirtualBox をアップデートすると結構な確率で Docker Machine が動かなくなったりしたので、ピンしてバージョンを固定します(バージョナップはアンインストール→インストール)。
choco install -y virtualbox
choco pin add -n virtualbox
Docker Toolbox をインストールします。
choco install -y docker-toolbox
WSL に必要なものをインストール
WSL に Docker をインストールします。ubuntu 用のパッケージリポジトリがあるのでそちらからインストールします。
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce
docker-compose
と docker-machine
もインストールします。それぞれ Github にビルド済バイナリがあるのでダウンロードしてパスの通ったところに配置します。
Docker Machine を作成
Windows 側で Docker Machine を作成します。--virtualbox-share-folder
を指定しているのがポイントです。これがないと WSL のパスとの対応が取れなくなります。詳細は後述します。
docker-machine.exe create default --driver=virtualbox \
--virtualbox-hostonly-cidr '192.168.99.1/24' \
--virtualbox-share-folder 'c:\Users:/mnt/c/Users'
次に、WSL の docker-machine
コマンドで↑で構築した Docker Machine を操作できるようにインポートします。--driver=generic
を指定すれば実行中のホストを SSH 経由で docker-machine
で制御できるようになります。--generic-ip-address
や --generic-ssh-key
では Windows 側の Docker Machine のものを指すように指定します。
docker-machine create default --driver=generic \
--generic-ssh-user="docker" \
--generic-ip-address="$(docker-machine.exe ip)" \
--generic-ssh-key="/mnt/c/Users/$USER/.docker/machine/machines/default/id_rsa"
これは必須ではないです。インポートすると言っても docker-machine start
や docker-machine stop
は --driver=generic
だとできないため、docker-machine ip
docker-machine ssh
ぐらいしか使わないと思います。これぐらいなら Windows 側の docker-machine.exe ip
とかを実行しても対して変わらないです。
WSL の docker
コマンドのための環境変数を設定します。
docker-machine env > "$HOME/.docker/env"
echo 'source "$HOME/.docker/env"' >> ~/.bash_profile
source "$HOME/.docker/env"
WSL の docker
コマンドから Windows の docker-machine にアクセスできていることを確認します。
docker ps
docker run --rm hello-world
マウントもできることを確認しておきます。
docker run -v $PWD:/app:ro --rm alpine ls /app
最後に、WSL側の Docker Machine の秘密鍵や証明書等のファイルを Windows 側の Docker Machine にコピーしておきます。
rsync ~/.docker/machine/machines/default/ \
"/mnt/c/Users/$USER/.docker/machine/machines/default/" \
--exclude config.json -av
WSL 側に --driver=generic
で Docker Machine をインポートしたときに Docker Machine の中で動いている Docker Engine にアクセスするための秘密鍵や証明書が更新されているので、そのままだと Windows 側の docker-machine.exe
コマンドでいくつかの操作ができなくなります。
ただ、docker-machine.exe start
や docker-machine.exe stop
は秘密鍵や証明書は無くてもできるので、あまり困りません(Windows 側の docker-machine.exe
ではこれぐらいの操作しかしない)
スタートアップ
スタートアップで Docker Machine を開始すると良いです。下記でスタートアップフォルダを開いて・・
explorer.exe shell:startup
次のようなショートカットを登録すれば OK です。
docker-machine.exe start
パスについて
docker-machine
はデフォルトではホスト(Windows)のディレクトリをゲスト(virtualbox)に c:\Users -> /c/Users
のようにマウントします。
Windows 上で docker-compose
コマンドを使う分にはこれで十分です。docker-compose
は c:\Users
のようなパスを自動的に /c/Users
に読み替えます(COMPOSE_CONVERT_WINDOWS_PATHS=true
環境変数が設定されていればですけど、docker-machine.exe env
に含まれています)。
しかし WSL から使う場合はこれだと不都合です。WSL ではホストのディレクトリが c:\Users -> /mnt/c/Users
のようにマウントされます。
したがって WSL で /mnt/c/Users/ore/vol
などをマウント元として指定するためには virtualbox でも c:\Users
が /mnt/c/Users
にマウントされている必要があります。
なので docker-machine の作成時に --virtualbox-share-folder
で次のように指定しています。
docker-machine.exe create default --driver=virtualbox \
--virtualbox-hostonly-cidr '192.168.99.1/24' \
--virtualbox-share-folder 'c:\Users:/mnt/c/Users'
なお、↑のように Docker Machine を作ると、逆に Windows 上の docker-compose.exe
ではパスの対応がとれなくなってしまうので使い物にならなくなります。PhpStorm で docker-compose
を設定するときは Windows 上の docker-compose.exe
が使用されるので注意が必要です。
WSL の設定でホストのディレクトリが c:\Users -> /c/Users
とマウントされるようにしても良いのかもしれません、これなら WSL と Windows の両方の docker-compose
を活かすことができるかも(未確認)。
さいごに
Docker for Windows は Hyper-V が必要で、Hyper-V は VirtualBox と共存できなくて、VirtualBox は vagrant に必要なので、Docker for Windows は使ってません。なので Docker for Windows を WSL から使えるかどうかはわかりません。
vagrant はもうほとんど使っていないので、もし WSL から Docker for Windows が使えるなら Docker for Windows に乗り換えたほうが良いかもしれません(ただしそれでパスの問題が解決するかはわからない)。