Windows(主に32bit版)でDockerを利用する方法まとめ

WindowsでDockerを利用する場合、利用方法がいくつかありそうなので調べてみた。
というより手元に、Windows7の32bit版があるので、こいつで簡単にDockerできる方法を知りたかっただけ。

念のため補足すると、
あくまでLinuxベースのコンテナを利用したDockerの話であり、
Windowsコンテナを実現する[Windows 上の Docker エンジン](https://msdn.microsoft.com/ja-jp/virtualization/windowscontainers/docker/configure_docker_daemon)の話ではありません。

# Windows で Dockerを利用する公式の方法

[公式サイト](https://docs.docker.com/docker-for-windows/)によれば、Windows で Docker を使う場合、大きく2つの方法がある。

* Docker For Windows
* Docker Toolbox

## Docker For Windows

Windows のネイティブサポート版で、以下前提。

* 64bit Windows 10 Pro, Enterprise and Education (1511 November update, Build 10586 or later)
* Microsoft Hyper-V を利用する

## Docker Toolbox

Windows 7 など、Docker For Windows が使えない場合に利用する以前からある方法。
Dockerを利用するために必要なコンポーネントをひとまとめにしたセットで、以下が実際にインストールされるかと思う。

* Docker Client for Windows
* Docker Machine for Windows
* Docker Compose for Windows
* Kitematic for Windows
* Oracle VM VirtualBox
* Git for Windows

ただしこちらも少なくとも64bit環境でないとインストールできない。

## 32bit版 Windows 7 でDockerを使うには?

簡単に言えばDockerが動作可能な仮想環境(64bit版)を作り、そこで動かせばよい。

ただし32bit版Windowsで、64bit版の仮想環境を作成する必要があるので、
少なくとも[VirtualChecker](http://forest.watch.impress.co.jp/library/software/virtualcheck/)等で仮想化機能をサポートしているか確認するのが簡単かと思われる。

サポートしていなければあきらめる。

# Vagrant + VirtualBox を利用した方法

仮想環境の管理・構築には、Vagrant + VirtualBox を利用するとして、その場合以下の方法が考えられる。

1. Dockerをサポートしている仮想OSを利用
2. PROVISIONER としてDockerを利用
3. PROVIDER としてDockerを利用
4. Docker向けディストリビューションを利用

## 1. Dockerをサポートしている仮想OSを利用

例えば`centos7.2`の仮想環境を作れば、そこでDockerは利用できる。
ただしこの方法をやるぐらいなら次の [2. PROVISIONERとしてDockerを利用] のほうが良い。

## 2. PROVISIONERとしてDockerを利用

Vagrantのプロビジョナとして[DOCKER PROVISIONER](https://www.vagrantup.com/docs/provisioning/docker.html)を利用する方法。

```ruby:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  # 例として centos7.2 を利用する
  config.vm.box = "centos7.2"

  # Windowsから直接コンテナを見に行けるように
  config.vm.network "private_network", ip: "192.168.33.10"

  # Dockerfile の場所を指定してやる
  config.vm.provision "docker" do |d|
    d.build_image "/vagrant"
  end
end
```

上記設定で`vagrant up`すれば`centos7.2` の仮想環境が立ち上がり、自動的にDockerもインストールしてくれる。

今回は`build_image`でDockerfileの場所を指定し、ビルドまでをやってみた。
なおDockerfileはVagrantfileと同じ場所に、テスト用に`FROM`だけ指定して作成済み。

```:Dockerfile
FROM training/webapp
```

### 結果

実際にやってみた。

```sh
# メッセージ出力は一部のみ掲載
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'centos7.2'...
==> default: Machine booted and ready!
==> default: Running provisioner: docker...
    default: Installing Docker onto machine...
==> default: Building Docker images...
==> default: -- Path: /vagrant
==> default: Sending build context to Docker daemon 13.82 kB
==> default: Step 1 : FROM training/webapp
==> default: Successfully built 6fae60ef3446
```

確認として仮想環境にてコンテナを立ち上げてみる。

```sh
# 仮想環境に接続
$ vagrant ssh
# docker が確かに入っている
[vagrant@localhost ~]$ docker -v
Docker version 1.12.3, build 6b644ec
# イメージが出来ている
[vagrant@localhost ~]$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
training/webapp     latest              6fae60ef3446        17 months ago       348.7 MB
# コンテナを作成
[vagrant@localhost ~]$ docker run -dP training/webapp
88d37a5e57d3fb2641f20641e7752a1ec6aa711b2d1252465d609e86910cb96d
# ポートを確認
[vagrant@localhost ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
88d37a5e57d3        training/webapp     "python app.py"     34 seconds ago      Up 33 seconds       0.0.0.0:32768->5000/tcp   focused_wilson
```

最後にホスト(32bit版 Windows 7)から接続できることを確認。

```sh
$ curl 192.168.33.10:32768
Hello world!
```

もちろんブラウザからも参照できた。

![ie.png](https://qiita-image-store.s3.amazonaws.com/0/14471/eab0d6ce-5aee-fd09-731f-8d0379358db4.png)


## 3. PROVIDERとしてDockerを利用

Vagrantのプロバイダとして[DOCKER PROVIDER](https://www.vagrantup.com/docs/docker/basics.html)を利用する方法。

```ruby:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.provider "docker" do |d|
    d.image = "training/webapp"
  end
end
```

VagrantのプロバイダとしてDocker利用すれば、
Dockerが利用可能な環境を勝手に提供してくれるらしいが…

### 結果

```sh
$ vagrant up
...
Bringing machine 'default' up with 'docker' provider...
No synced folder implementation is available for your synced folders!
Please consult the documentation to learn why this may be the case.
You may force a synced folder implementation by specifying a "type:"
option for the synced folders. Available synced folder implementations
are listed below.

docker, nfs, rsync, smb, virtualbox
```

同期フォルダの作成でエラー発生。
`rsync`を入れてもどうも動きが怪しかったので深入りせずに早々に切り上げた。

というのもどうもやっていることは[こちらのBoot2Docker](https://atlas.hashicorp.com/hashicorp/boxes/boot2docker)を裏で利用する仕組みらしい。

```sh
# Boot2Dockerが追加されている
$ vagrant box list
hashicorp/boot2docker (virtualbox, 1.7.8)
```

なので直接をこの`hashicorp/boot2docker`を利用しても同じっぽいので次で確認する。

## 4. Docker向けディストリビューションを利用

いわば [1. Dockerが動作する仮想OSを利用] とほぼ同じ方法だが、
Docker向けディストリビューションの利用すればDockerのインストール等が不要なので楽。

というわけで、早速先ほどの`hashicorp/boot2docker`を利用しようと思ったが

```sh
$ vagrant init hashicorp/boot2docker
$ vagrant up

# 実際に接続してバージョンを確認
$ vagrant ssh
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 1.7.0, build master : 7960f90 - Thu Jun 18 18:31:45 UTC 2015
Docker version 1.7.0, build 0baf609
```

Docker のバージョンがやや古いのでやっぱりこれを使うのは控えておく。

### Docker向けのディストリビューション

主要なもので3つ [^1]

* [CoreOS](https://coreos.com/)
* [Project Atomic](http://www.projectatomic.io/)
* [Snappy Ubuntu Core](http://developer.ubuntu.com/en/snappy/)

それ以外にも以下のようにいろいろと存在する模様[^2]

* [Barge OS](https://github.com/bargees/barge-os)
* [RancherOS](https://github.com/rancher/os)
* [Boot2Docker](https://github.com/boot2docker/boot2docker)
* [DhyveOS](https://github.com/nlf/dhyve-os)

[^1]: [Docker向けの軽量Linux OS 主要3種を比較する](https://thinkit.co.jp/story/2015/03/06/5672)
[^2]: [メモ：Docker ホスト用軽量 OS の比較](http://qiita.com/A-I/items/3d2aedbad4f10141cef3)

この中でも特に軽そうな`Barge OS`を利用してみる。

公式の設定を参考に Vagrantfile を作成する

```ruby:Vagrantfile
# A dummy plugin for Barge to set hostname and network correctly at the very first `vagrant up`
module VagrantPlugins
  module GuestLinux
    class Plugin < Vagrant.plugin("2")
      guest_capability("linux", "change_host_name") { Cap::ChangeHostName }
      guest_capability("linux", "configure_networks") { Cap::ConfigureNetworks }
    end
  end
end

Vagrant.configure(2) do |config|
  config.vm.define "barge"
  config.vm.box = "ailispaw/barge"

  config.vm.synced_folder ".", "/vagrant"
  config.vm.network "private_network", ip: "192.168.33.10"

  # 今回はbuildだけでなくrunまでやってみる
  config.vm.provision :docker do |d|
    d.build_image "/vagrant"
    # ポートも指定しておく
    d.run "webapp", image: "training/webapp", args: "-p 8080:5000"
  end
end
```

なおDockerfileは先ほど同様、Vagrantfileと同じ場所に`FROM`だけ指定して作成済み。

```:Dockerfile
FROM training/webapp
```

### 結果

あとは起動するだけで、コンテナの立ち上げまで完了している。

```sh
$ vagrant up
# ちなみにDockerのバージョンは
$ vagrant ssh
# ちょっと古いが
[bargee@barge ~]$ docker -v
Docker version 1.10.3, build 20f81dd
# 最新バージョンに切り替えられる
[bargee@barge ~]$ sudo /etc/init.d/docker restart latest
[bargee@barge ~]$ docker -v
Docker version 1.12.3, build 6b644ec
```

最後にブラウザで確認

![ie2.png](https://qiita-image-store.s3.amazonaws.com/0/14471/8c766619-ecdb-8e5a-75ca-bc97160ee518.png)


# Docker Machine を利用した方法

Docker Toolbox は 64bit環境 が前提だが、
実はその構成要素である Docker Machine なら 32bit版Windows 7 でも利用できる。

なのでVagrantを利用していないなら、Docker Machine を利用するのが一番楽かも。

## インストール

[こちら](ttps://github.com/docker/machine/releases/)から実行ファイルをダウンロードするだけだが、
VirtualBox は必要なので事前にインストールしておく必要はある。

なお [chocolatery](https://chocolatey.org/)を利用しているなら以下だけでＯＫかと。

```sh
$ cinst VirtualBox
$ cinst docker-machine
```

## 結果

```sh
$  ./docker-machine-Windows-i386.exe create --driver virtualbox dockerhost
```

これだけで Boot2Docker がダウンロードされ、VirtualBox にて実行された。
公式のツールなので安心感があり、Dockerのバージョンも新しい。

```sh
$ ./docker-machine-Windows-i386.exe ls
NAME         ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER    ERRORS
dockerhost   -        virtualbox   Running   tcp://192.168.99.100:2376           v1.12.3

# 接続してコンテナを起動してみる
$  ./docker-machine-Windows-i386.exe ssh dockerhost
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 1.12.3, build HEAD : 7fc7575 - Thu Oct 27 17:23:17 UTC 2016
Docker version 1.12.3, build 6b644ec
docker@dockerhost:~$ docker run -d -p 8080:5000 training/webapp python app.py
# うん、立ち上がっている
docker@dockerhost:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
5afdbdbd221c        training/webapp     "python app.py"     1 minutes ago       Up 1 minutes        0.0.0.0:8080->5000/tcp   cocky_brahmagupta
```

同様にブラウザからも確認できました。

![ie3.png](https://qiita-image-store.s3.amazonaws.com/0/14471/8e64a9db-2561-771d-8080-961a17f9babb.png)

Docker Machine は [Amazon EC2 や Microsoft Azure などクラウドにも対応](https://docs.docker.com/machine/get-started-cloud/)している。

# まとめ

64bit版Windowsなら素直に Docker For Windows か、Docker Toolbox を利用すればよいが、
32bit版Windowsなら Docker Machine が比較的簡単だと思われる。

すでにVagrantを利用しているなら`barge`などがさくっと使えて便利かも。