前回までのその1とその2では、いろいろな手法で簡単にDockerを使った仮想環境が動くことや、WordPressを動かせるDockerの使用方法を試してきました。
実際に試してみてDockerの簡単さや速さ、手軽さを実感することはできましたが、実際に目指しているのはDockerを使った開発環境の整備です。ただWordPressが動けばいいというものではなく、開発メンバーやデザイナーたちに実際に開発環境として使ってもらえることが目標です。
今後は、実際にWordPressのテーマ開発などができそうな環境を目指す上で必要な対処を行っていきたいと思います。
コンテナのデータが消えてしまう問題
これまでの例では、WordPressが動く環境ではあるものの、コンテナを消してしまうとWordPressの設定も変更したテンプレートもデータベースの内容も復元されず、次に同じコンテナを起動してもWordPressの初期画面からやりなおしになってしまっていました。せっかくの開発中のデータが途中でなくなってしまうようでは使いやすい環境とは言えないので、今回はこの問題について調べてみました。
Dockerのマウント機能
このデータが消えてしまう問題は、Dockerでは基本的にコンテナを消すと中の状態を復元することができないことが理由です。コンテナ内で作成や編集をしたファイルやフォルダは、コンテナを削除してしまうと消えてしまいますが、Dockerのマウント機能を使えばコンテナを削除しても消えないようにすることができます。
Dockerのマウント機能には、この記事を書いている時点では以下の三種類のマウント方法があります。
方法 | 説明 |
---|---|
バインドマウント (bind) | Dockerホスト上のデバイスファイルやディレクトリをコンテナに見せる |
ボリュームマウント (volume) | Dockerホストが管理するボリュームをコンテナに見せる |
一時ファイルシステムマウント (tmpfs) | Dockerホストのメモリをファイルシステムとしてコンテナに見せる |
今回は、Dockerでも初期の頃から提供されていて、データを保存する目的にも適している バインドマウント(bind) について重点的に調べてみました。
実際にコンテナを起動する際に使うと作成したファイルが保存されるのか、コンテナ内でファイルを作成して確認します。
$ docker run --rm --name test -v /Users/kiriyama/Documents/docker/testmount:/home -it debian:latest sh
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
e4c3d3e4f7b0: Pull complete
Digest: sha256:8414aa82208bc4c2761dc149df67e25c6b8a9380e5d8c4e7b5c84ca2d04bb244
Status: Downloaded newer image for debian:latest
# cd /home
# ls
# echo 'Hello World!!' > test.txt
# ls
test.txt
# exit
上記では -v
オプションでコンテナ内のパス/home
を、ホスト側の/Users/kiriyama/Documents/docker/testmount
にマウントしています。
コンテナの起動後、コンテナ内の/home
に移動し、テキストファイルtest.text
を作成してexit
でコンテナのシェルから抜けています。
起動時に--rm
オプションをつけていますので、exit
でコンテナの停止とともにコンテナは削除されますが、作成したファイルtest.txt
が中身も含めてどうなっているか、もう1度同じコマンドで確認します。
$ docker run --rm --name test -v /Users/kiriyama/Documents/docker/testmount:/home -it debian:latest sh
# cd /home
# ls
test.txt
# cat test.txt
Hello World!!
再度起動したあとも/home
に保存したファイルが中身とともに残っていますね。このバインドマウントを使えば、データを永続的に使用することができそうです。
Docker Composeでのデータの保存
Dockerコマンドではマウント機能で保存できましたが、Docker Compose
を使った場合にはどのようにするのが良いか、改めてこちらのマニュアルを確認してみると……
Compose は、サービスによって利用されているボリュームをすべて保護します。docker-compose up が実行されたときに、コンテナがそれ以前に実行されていたものであれば、以前のコンテナから現在のコンテナに向けてボリュームをコピーします。この処理において、ボリューム内に作り出されていたデータは失われることはありません。
という記載がありました。
以前のコンテナがあれば現在のコンテナに向けてコピーする機能のようですが、Docker Compose
でもデータが保護される機能があるのは間違いなさそうです。
早速この機能を使って、前回のその2で作成したdocker-compose.yml
を元に、実際にデータが失われないかテストしてみます。
version: '3'
services:
mysql:
image: mysql
restart: always
volumes: # 今回追加
- ./mysql:/var/lib/mysql # ホスト側の ./mysql をコンテナ内の /var/lib/mysql にマウント
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- mysql
image: wordpress
volumes: # 今回追加
- ./wordpress:/var/www/html # ホスト側の ./wordpress をコンテナ内の /var/www/html にマウント
ports:
- "8080:80"
restart: always
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
上記のservices > mysql > volumes
では、 ホスト側のパス ./mysql
にコンテナ内の/var/lib/mysql
をマウントする形を定義しています。WordPressのコンテンツも同様に保存されるようvolumesを設定しています。
$ docker-compose up -d
Creating network "part3_default" with the default driver
Pulling mysql (mysql:)...
latest: Pulling from library/mysql
:
49e112c55976: Pull complete
Digest: sha256:8c17271df53ee3b843d6e16d46cff13f22c9c04d6982eb15a9a47bd5c9ac7e2d
Status: Downloaded newer image for mysql:latest
Pulling wordpress (wordpress:)...
latest: Pulling from library/wordpress
:
Digest: sha256:20bffad04c9c3e696b3c6fbc48d769c5948718b57af8c9457d9a0f28b5066b4b
Status: Downloaded newer image for wordpress:latest
Creating part3_mysql_1 ... done
Creating part3_wordpress_1 ... done
一部省略していますが、コンテナの起動後は、ホスト側では以下のようなフォルダ構成になっています。
$ tree ./ -L 2
./
├── docker-compose.yml
├── mysql
│ ├── #ib_16384_0.dblwr
│ ├── #ib_16384_1.dblwr
│ ├── #innodb_temp
│ ├── auto.cnf
│ ├── binlog.000001
:
:
│ └── wordpress
└── wordpress
├── index.php
├── license.txt
├── wp-admin
:
:
└── xmlrpc.php
この状態でブラウザからhttp://localhost:8080
にアクセスして、WordPressの初期設定を行いました。
これで、初期設定のデータベースのデータや一部のコンテンツファイルが書き換えられたはずですので、コンテナを停止しつつイメージも含めてクリーンな状態にします。
$ docker-compose down --rmi all
Stopping part3_wordpress_1 ... done
Stopping part3_mysql_1 ... done
Removing part3_wordpress_1 ... done
Removing part3_mysql_1 ... done
Removing network part3_default
Removing image mysql
Removing image wordpress
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$
docker ps -a
で見ても、コンテナは削除されています。再度、同じように起動します。
kiriyama:part3$ docker-compose up -d
Creating network "part3_default" with the default driver
:
:
Creating part3_mysql_1 ... done
Creating part3_wordpress_1 ... done
ブラウザで再度http://localhost:8080
にアクセスすると、初期設定画面ではなく、設定したのWordPressの画面が表示されましたので、WordPressのコンテンツとデータベースのデータが保存されていることが確認できました。
Dockerを使って開発環境の整備はできるか
今回はコンテナを削除してしまうとコンテナ内のデータが削除されてしまう問題について調べてみました。
実際にマウント機能をつかってみると思った以上に簡単で、特にDocker Compose
のvolumes
の使い勝手がかなり良く、ホスト側から簡単に参照したり編集したりできるので、サーバ側ミドルウェアの設定のテスト等にも応用できそうです。
次回は、実際に開発メンバーが使っている統合開発環境やソースコードのバージョン管理システムに対応できるような、より現実的なDockerを使った開発環境を検証してみたいと思います。