docker for windows を始める

よくあるdocer for windows の記事が「インストールしてkitematicのイメージを実行して終わり」ばかりだったのでもうちょっと先まで書いてみる。

## 目標

docker for windows で nginx を起動し、ローカルホストにある hello.htmlを表示する

## docker for windows のインストール

対象はwindows10 professional以上。

* 管理ツールとかで hyper-vを有効にする
* 公式からダウンロードしたインストーラーを実行する。オプションはすべてデフォルト。

インストールが終わったら デスクトップにあるdocker for windowsアイコンからdockerを起動する。(もしかしたらインストール終了時に起動しているかも)

## 初期設定

ローカスホスト上のファイルを docker containerから読めるようにしたいので、その設定。

*タスクアイコンの docker を右クリックし、settings を開く。
* Shared Drives にある リストから docker hostとローカルホストで共有するドライブのチェックをONにする

## composeするコンテナの構成を考える

nginx サービスを立ち上げ、ドキュメントルートをローカルホストに配置して編集可能にする。
nginxサービスは既存のイメージから作成する。

### ディレクトリ構成

こんな感じで。

```
foo
│  docker-compose.yml
├─html
│      hello.html
│      index.html
└─nginx
        default.conf
        Dockerfile
```

html ディレクトリにコンテンツファイルを置き、nginxのドキュメントルートとしてマウントする。

## docker-composeとDockerファイルの記述

まず docker-compose.ymlの記述。

```docker-compose.yml
nginx: 
  build: ./nginx
  ports: 
    - "8080:80"
  volumes:
    - ./html/:/var/www/html/
```
nginxサービスは nginx/Dockerfileの記述からイメージを作成する。
port はコンテナの 80 を ローカルホストの8080にフォワード。マウントするボリュームは コンテナの /var/www/html を html/ に割り当てる。

ボリュームがマウントされるイメージはこんな感じ

```
ローカルホストの ./html/ ---- コンテナの /var/www/html
```

次、nginx/Dockerfileの記述。

```:nginx/Dockerfile
FROM nginx:1.11.5

MAINTAINER mic okada <okadabasso@gmail.com>

COPY default.conf /etc/nginx/conf.d/default.conf
```
公式の nginxイメージを使用する。nginx/default.conf を新しいイメージの/etc/nginx/conf.d/default.conf にコピーする。

default.conf はこんな感じ。

```nginx/default.conf
server {
    listen       80;
    server_name  localhost;

    charset utf-8;
 
    location / {
        root   /var/www/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```
ドキュメントルートは /var/www/htmlにしてある。この場所がローカルの html/に当たる。

表示する hello.html はこう。

```html
<html>
    <head></head>
    <body>
        <p>hello container</p>
    </body>
</html>
```

まあ、サンプルだし。

## コンテナイメージのビルド

コンテナイメージをビルドする。

```
c:\...\foo> docker-compose.exe build
```
できたイメージを確認。

```
c:\...\foo> docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
foo_nginx                     latest              cb89d9940409        18 hours ago        181MB
```

このまま `c:\...\foo> docker run foo_nginx` とかしても起動できるけど、それだとポートのフォワードもボリュームのマウントもしてくれないし、それらをコマンドラインで指定するのもいいけど折角docker-compose使う意味がない。

## コンテナを起動する

いよいよ起動。

```
c:\...\foo> docker-compose up -d
Creating foo_nginx_1 ...
Creating foo_nginx_1 ... done
C:\...\foo>
```

こういう出力になればOK. ブラウザで http://localhost:8080/hello.html にアクセスすると、 html/hello.html に書いた内容が表示される、はず。

起動したコンテナを一時停止するなら

```
c:\...\foo> docker-compose stop
```

こうするとサービスは停止するけどコンテナは残ったままになる。
一方

```
c:\...\foo> docker-compose down
```

こうしたらサービスが停止し、コンテナは削除される。


## その他

ボリュームにマウントするディレクトリの場所を理解するのに結構かかった。サンプルとかでマウントするボリュームが絶対パスで書かれてる場合(/var/www/appとか)、それはdockerホスト内のパスになってしまうから docker for windowsだとアクセスできない。絶対パスで指定する場合は c:/path/to/volume みたいに初期設定で共有したドライブを基準に"\"を "/"に書き換えた形で指定しないとダメ。

railsとかphp/composerで開発するならdocker exec bashとかでコンテナ内のシェルを使うことになると思う。

あと、重要なこと。

docker for windows は hyper-vを使う都合上、virtualboxなどのVMが使えない。使おうとするとブルースクリーン。vagrantと併用しようとする場合はhyper-v対応のboxを使う必要がある。