Windows10にDockerでLAMP環境を構築する　その2

[前回](http://qiita.com/kamonamban/items/e0150a2a7a4d28db10c4)に引き続き、LAMP環境を作っていきます。

```
$ docker --version
Docker version 1.11.2, build b9f10c9
$ docker-compose --version
docker-compose version 1.7.1, build 0a9ab35
```

### データの永続化

定時になったのでもう帰りましょう。
PCを落とさなければいけないので、その前に立ち上げたコンテナを消しておきます。

```
$ docker-compose down
```

翌日、改めてコンテナを立ち上げ、アクセスしてみると……。

> 403 Forbidden

( ‘ᾥ’ )

おいどういうことだ昨日作ったindex.phpちゃんはどこに行った。

```
$ docker exec -it sandbox_web_1 bash
# ls
#
```

し、死んでる……。
それどころかvim君まで死亡確認。

何が起きたかというと簡単な話です。`docker-compose down`でコンテナを消してしまうと、そこでの作業はすべて消えてしまいます。
コンテナを文字通り箱だとします。箱そのものを潰して新しく箱を組み立てたわけですから、潰した箱の中身がそこにあるはずがありません。
これのを防ぐ対応がデータの永続化です。

方法はいくつかありますが、ここでは一番簡単な方法を使います。ホストOSとディレクトリを共有してしまうのです。
docker-compose.ymlを編集します。

``` docker-compose.yml
version: "2"

services:

  web:
    image: php:5.6-apache
    ports:
      - "80:80"
    volumes:
      - ./html/:/var/www/html

  db:
    image: mysql:5.7
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
```

webにvolumesという値を追加しました。
改めてコンテナを立ち上げてみます。

```
$ docker-compose up -d
$ ls
docker-compose.yml html/
```

おもちゃ箱に勝手に新しいフォルダが作成されています。
webコンテナの/var/www/htmlとホストOSの~/sandbox/html/を共有させたためです。
~/sandbox/html/にindex.phpを作ってみます。

```
$ touch html/index.php
```

``` ~/sandbox/html/index.php
<?php echo 'made from windows';
```

さて、アクセスしてみると……。

> made from windows

( •̀ㅂ•́)و

試しにコンテナの再生成をしてみましょう。

```
$ docker-compose down
$ docker-compose up -d
```

もう403は発生しません。やったぜ。

コンテナとホストOSのディレクトリを共有できるということは、ここにEclipse等のプロジェクトを作ってしまえば、編集内容が直接反映するようになります。
よかった、viで開発するエンジニアはいなかったんだ。

### MySQLの永続化

続いてdbを見てみます。
mysqlコンテナで作業します。mysqlのrootユーザーのパスは、docker-compose.ymlで指定してあります。

```
$ docker exec -it sandbox_mysql_1 bash
# mysql -uroot -p
mysql> create database sandbox;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sandbox            |
| sys                |
+--------------------+
```

sandboxスキーマが作成されました。
コンテナを抜け、再生成、スキーマを確認します。

```
$ docker-compose down
$ docker-compose up -d
$ docker exec -it sandbox_mysql_1 bash
# mysql -uroot -p
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
```

知ってた。

webと同じようにmysqlのデータディレクトリとホストを共有させるのも手ですが、ここはデータコンテナを使ってみましょう。
データコンテナは、データボリュームコンテナとかストレージコンテナとかやたら表記揺れする機能で、文字通りデータを収めるため「だけ」のコンテナです。
Wizardryの倉庫キャラみたいなものでしょうか。

docker-compose.ymlを編集します。

``` docker-compose.yml
version: "2"

services:

  web:
    image: php:5.6-apache
    ports:
      - "80:80"
    volumes:
      - ./html/:/var/www/html

  db:
    image: mysql:5.7
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes_from:
      - data

  data:
    image: busybox:1
    volumes:
      - /var/lib/mysql:/var/lib/mysql
```

busyboxはlinuxを構成する最小限の構成で組まれているイメージです。倉庫キャラにはもってこいです。
dbにvolumes_fromという項目が加わっています。dbコンテナとdataコンテナの構造を同期させています。
その上で、dataコンテナの/var/lib/mysqlをホストと同期させます。

（○'ω'○）ん？　それじゃ結局mysqlのデータはWindowsに保存されるの？

ホストとは、正確にはDockerが動作しているVirtualBoxの仮想マシンのことです（ここ書きながら検証してて知った）。
Windows <--共有--> VirtualBox <--共有--> コンテナ
こんなイメージ。
よって、mysqlのデータはVirtualBox上に保存されます。
四の五の言わずに試してみましょう。

```
$ docker exec -it sandbox_mysql_1 bash
# mysql -uroot -p
mysql> create database sandbox;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sandbox            |
| sys                |
+--------------------+
```

コピペで済むから楽だわ～。

```
$ docker-compose down
$ docker-compose up -d
$ docker exec -it sandbox_mysql_1 bash
# mysql -uroot -p
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sandbox            |
| sys                |
+--------------------+
```

無事、データの永続化ができました。

### 何でこんなことするの？

dbコンテナに直接volumeを書いてしまえばいいものを、なぜこんな回りくどいことをするのか。
実は、既存のコンテナを元にイメージを作成することができます。つまり、データコンテナを元にイメージを作れば、データが持ち運べ

＿人人人人人人＿
＞　ません！　＜
￣Y^Y^Y^Y^Y^Y￣

コンテナをイメージ化しても、ボリューム上のデータは保存できません。
便利だと思ったんだけど……。

ではなぜデータコンテナを使うのか。

なんでなんでしょうね？　城跡らしいので、きっといい方法なのでしょう。
あまり気にすると毛根に悪いので、次行きましょう。次。

### さーて次の

データの永続化とホストとのディレクトリ共有ができました。
しかしこれではまだLAP環境とM環境ができただけです。次はPHP側からMySQLへの接続を行っていきます。

今回疎通までやるとキッパリ書いたばかりだったのに……スマンありゃウソだった。
でもまぁ、永続化はちゃんと調べられた。だから良しとするって事でさ……。
こらえてくれ。

--> [Windows10にDockerでLAMP環境を構築する　その3](http://qiita.com/kamonamban/items/ec1f2e755d86f1b4bd05)