前回に引き続き、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を編集します。
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
<?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を編集します。
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への接続を行っていきます。
今回疎通までやるとキッパリ書いたばかりだったのに……スマンありゃウソだった。
でもまぁ、永続化はちゃんと調べられた。だから良しとするって事でさ……。
こらえてくれ。