Docker for Windows で遊んでみた

#Docker について
開発環境をいろいろ試してみたくなり、調べたところ Docker がおもしろそうなので遊んでみた。

とりあえず、MacBook(2016 m3 8GB) に Docker for Mac に入れてみたところ、結構簡単に動く。
これに味をしめて、Windows でも入れてみたところ、いくつかつまづくところがあったのでメモしておきます。

#PCスペック
- PC: Thinkpad E470 i5-7200U 24GB SSD512GB
メモリ16GB追加、HDDからSSDに換装。cpu は、i5 に抑えてその分メモリを増やしています。
もちろん、こんなにメモリを積まなくても動作します。

- OS: Windows10 Home から Windows10 Pro に変更
Docker for Windows を使うには、Windows10 Pro が必要とのことで、Windowsストアで変更
※Docker Toolbox を使えば、Windows10 Home でも動作するはずだが、せっかくなので Docker for Windows にした。Docker 使用時にえらく軽くなるはず。

#Hello World on Docker
最初は、Hello World。Power Shell から起動します。

```
>docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Image is up to date for hello-world:latest

> docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
hello-world               latest              c54a2cc56cbb        5 months ago        1.848 kB

> docker run 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.
 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 Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/
```

Hello World は、起動してメッセージ出力後にすぐ終了します。
docker ps で、「現在起動しているコンテナ」を表示しても起動中のコンテナはありません。

```
> docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED              STATUS                          PORTS                NAMES
```

docker ps -a で、「すべてのコンテナ」を表示すると Hello World のコンテナが表示されます。

```
> docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED              STATUS                          PORTS                NAMES
9d08b32426d0        hello-world         "/hello"             About a minute ago   Exited (0) About a minute ago                        romantic_bassi
```

##Hello World 再実行
docker start -a 9d で、コンテナを再実行できます。
コンテナIDは、2桁以上でユニークであれば短縮できます。

```
> docker start -a 9d

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.
 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 Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/
```

##コンテナの削除。
コンテナIDを指定して、削除します。

```
> docker rm 9d
9d

> docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                  PORTS               NAMES
```

##image の削除

```
> docker rmi hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Deleted: sha256:c54a2cc56cbb2f04003c1cd4507e118af7c0d340fe7e2720f70976c4b75237dc
Deleted: sha256:a02596fdd012f22b03af6ad7d11fa590c57507558357b079c3e8cebceb4262d7
```

#ubuntu の起動
次に、Hello World で、ubuntu を試してみろとあるので、起動します。
初回は、ubuntu:latest の image が自動的に pull されて、指定した bash に入ります。

```
> docker run -it ubuntu bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu

b3e1c725a85f: Pull complete
4daad8bdde31: Pull complete
63fe8c0068a8: Pull complete
4a70713c436f: Pull complete
bd842a2105a8: Pull complete
Digest: sha256:7a64bc9c8843b0a8c8b8a7e4715b7615e4e1b0d8ca3c7e7a76ec8250899c397a
Status: Downloaded newer image for ubuntu:latest
root@a895307441ce:/# ubunts -vercat /etc/lsb-release^C
root@a895307441ce:/# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"
root@a895307441ce:/#
```

##ubuntu の終了
bash をexit で抜けると、コンテナもそのまま終了します。

```
root@a895307441ce:/# exit
exit

> docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

> docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                     PORTS               NAMES
a895307441ce        ubuntu              "bash"               22 hours ago        Exited (0) 2 minutes ago                       hungry_kilby
```

##デタッチモードでの、ubuntu 起動(start)と追加プロセス(exec)を実行。

```
> docker start hungry_kilby
hungry_kilby

> docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a895307441ce        ubuntu              "bash"              23 hours ago        Up 5 seconds                            hungry_kilby

> docker exec -i -t a8 bash
root@a895307441ce:/#
```


##Windows ディレクトリをマウントして、ubuntu を起動
windows 側のディレクトリは、バックスラッシュで指定。
ディレクトリパス指定を間違うと、docker コマンドが何も効かなくなり、docker restart するしかありません。

```
> docker run -it -v \\c\Users\xxxxx\work:/var/work ubuntu bash
root@b6e6f1bd5fd4:/# ls /var/work
test1.txt  test2.txt
root@b6e6f1bd5fd4:/#
```

#docker-compose による lamp 環境
docker-compose を使って、コンテナをまとめて制御できる。とっても便利。
docker-compose.yml に必要なimage と設定を記述

http://localhost:8000 で web
http://localhost:8080 で phpmyadmin

```
mysql:
    image: mysql:5.7.11
    environment:
        - MYSQL_ROOT_PASSWORD=xxxxxxxxxxxxx
apache-php:
    image: php:5.6.19-apache
    ports:
        - "8000:80"
    volumes:
        - ./webroot:/var/www/html
    links:
        - mysql:db
phpmyadmin:
    image: phpmyadmin/phpmyadmin:4.5.3.1-1
    ports:
        - "8080:8080"
    links:
        - mysql:db
```

##docker-compose up
初回起動時は、image の pull から起動まで実行される

```
> docker-compose up -d
Pulling mysql (mysql:5.7.11)...
5.7.11: Pulling from library/mysql
efd26ecc9548: Pull complete
a3ed95caeb02: Pull complete
af2f7dea6ac4: Pull complete
...

Status: Downloaded newer image for phpmyadmin/phpmyadmin:4.5.3.1-1
Creating lamp1_mysql_1
Creating lamp1_apache-php_1
Creating lamp1_phpmyadmin_1
```

##docker-compose ps
起動確認

```
> docker-compose ps
       Name                    Command             State           Ports
---------------------------------------------------------------------------------
lamp1_apache-php_1   apache2-foreground            Up      0.0.0.0:8000->80/tcp
lamp1_mysql_1        docker-entrypoint.sh mysqld   Up      3306/tcp
lamp1_phpmyadmin_1   /run.sh                       Up      0.0.0.0:8080->8080/tcp
```

##docker-compose stop
停止と状態確認

```
> docker-compose stop
Stopping lamp1_apache-php_1 ... done
Stopping lamp1_phpmyadmin_1 ... done
Stopping lamp1_mysql_1 ... done

> docker-compose ps
       Name                    Command              State     Ports
-------------------------------------------------------------------
lamp1_apache-php_1   apache2-foreground            Exit 0
lamp1_mysql_1        docker-entrypoint.sh mysqld   Exit 0
lamp1_phpmyadmin_1   /run.sh                       Exit 137
```

##docker-compose rm
コンテナ削除

```
> docker-compose rm
Going to remove lamp1_apache-php_1, lamp1_phpmyadmin_1, lamp1_mysql_1
Are you sure? [yN] y
Removing lamp1_apache-php_1 ... done
Removing lamp1_phpmyadmin_1 ... done
Removing lamp1_mysql_1 ... done

```


#トラブル時の対応

##volume オプション指定ミスによるフリーズ
volume オプションに存在しないパスを指定すると、docker コマンドで応答が帰らず、そのまま固まってしまう。
対応としては、doker をrestart するしかない。

##port is already allocated
httpd 関連でトラブルと、再起動時に「port is already allocated」になる場合がある。
この場合は、doker をrestart しても解決しない。
Hyper-v マネージャーで、仮想マシン「MobyLinuxVM」を再起動後に、doker をrestart する。

```
ERROR: for apache-php  Cannot start service apache-php: driver failed programming external connectivity on endpoint lamp1_apache-php_1 (86120e9335f8162df
3835793018aa93314fc2b855bbc69150dd8ed3463162f84): Bind for 0.0.0.0:8000 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.
```