どうもこんにちは
久しぶりにDockerのことについて書きたいと思います、前回のDockerエントリが8/30ですね、はい。
今回はタイトル通りDockerでMySQLコンテナを立ち上げてデータを保存してみます。
きっかけ
僕が個人的にサービスを作ろうとした時に、環境を全部dockerコンテナで管理出来るようにしようと思ったところ「MySQLのデータってコンテナ内部に保存できるの?てかして良いの?」という疑問が出てきたので解決方法を調べてみました。参考資料はこちら
Docker でデータのポータビリティをあげ永続化しよう
Dockerのbusyboxは永続コンテナと言いながらexport/saveコマンドでは持ち運びできないよ
DockerとData Volume Containerのお話
やること
1.busyboxイメージを使ってデータ保存用のコンテナを立ち上げる 2.データ保存用コンテナを指定してMySQLコンテナを立ち上げる 3.MySQLにデータを追加する 4.busyboxでデータが指定ディレクトリに追加されているか確認 5.保存したデータを1.で立ち上げたコンテナとは別コンテナで扱う 6.嬉しむでは見ていきましょう
実践
busyboxを立ち上げる
保存するイメージはUbuntuやCentOSでもいいのですが、特に気にしないのであればbusyboxで行います。 これは上記の2つよりも軽量でストレージにしたい場合に使うことが多いようです。busyboxのDockerfileを作成します
ファイル名はDockerfileです。
FROM busybox
VOLUME /var/lib/mysql
CMD /bin/sh
これを元にイメージを作成します。
イメージビルド ```docker build -t strage_image .``` 歌いながら待ちます(白いブラウス似合う女の子〜なぜいつも悲しそうなの〜) ...
このイメージからコンテナを作成します。
docker run -it -v /var/lib/mysql --name strage_container strage_image
-v 指定ディレクトリ
でこのコンテナが他のコンテナから指定された時に関連付けられるディレクトリになります。
※DockerfileのVOLUMEにこのディレクトリを記述している場合、このパラメータは不要ですが今回は付けています。
strage_containerが作成されました。
MySQLコンテナを立ち上げる
先ほどのstrage_containerをデータ保存先に指定してコンテナを立ち上げます。docker run --volumes-from strage_container --name mysql_container -e MYSQL_ROOT_PASSWORD=pass -d -p 3306:3306 mysql
これでstrage_containerと/var/lib/mysqlディレクトリが共有された状態になりました。
MySQLコンテナにデータを追加(テキストファイル)
一旦テストファイルを配置して本当にstrage_containerと共有出来ているか確かめてみます。 mysql_containerにファイル配置ストレージコンテナでデータの確認(テキストファイル)
strage_containerでファイルが配置されているか確認 コンテナスタート `docker start strage_container`接続
docker attach strage_container
確かにstrage_containerでもtest.txtが確認出来ましたね。
ストレージコンテナにデータを追加(DBのデータ)
次はテーブルを作成してinsertしてそのデータを共有してみます。 ※先ほどのtest.txtはstrage_containerから削除しておきましょう。 /var/lib/mysql/にファイルがあるとMySQLを起動しようとした時にエラーが出ます。 ![スクリーンショット 2015-12-31 20.01.12.png](https://qiita-image-store.s3.amazonaws.com/0/36871/8d1d8970-a18c-f72a-a3b2-12803e835ebd.png "スクリーンショット 2015-12-31 20.01.12.png")コンテナのbashを抜けた状態&コンテナはstartしている状態で
docker exec -it mysql_container bash
MySQL接続
mysql -u root -p
passwordは先程runした時MYSQL_ROOT_PASSWORDに設定した値です。
今回はpassと入力してください。
INSERT文を実行してデータを追加していきたいと思います。
まずは適当にDBとテーブルを作成
CREATE SCHEMA IF NOT EXISTS `docker_scheme` DEFAULT
CHARACTER SET utf8 ;
USE `docker_scheme` ;
DROP TABLE IF EXISTS `docker_scheme`.`users` ;
CREATE TABLE IF NOT EXISTS `docker_scheme`.`users` (
`id` INT NOT NULL AUTO_INCREMENT,
`nick_name` VARCHAR(32) NOT NULL DEFAULT '',
`age` INT NOT NULL DEFAULT 18,
`introduce` VARCHAR(2048) NOT NULL DEFAULT '',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `AGE` (`age` ASC))
ENGINE = InnoDB;
DBとテーブルが作成されたことを確認しましょう。
次にこのクエリを実行してデータを入れます。
データ自体は何でもいいです。
INSERT INTO users(`nick_name`, `age`, `introduce`)
VALUES('takashi', 21, 'Server side programmer');
ストレージコンテナでデータの確認(DBのデータ)
ここで一旦, mysql_containerから出てstrage_containerの中身を確認してみます。 ![スクリーンショット 2015-12-31 20.22.06.png](https://qiita-image-store.s3.amazonaws.com/0/36871/d7a91bd8-5b40-8d36-9d75-022e1107c3fe.png "スクリーンショット 2015-12-31 20.22.06.png")色々出来ていますね、良さそうです。
strage_containerに保存したデータをmysql_containerとは別のコンテナでデータを扱う
先程はmysql_containerという名前のコンテナからデータを入れていました。 次はmysql_container2というコンテナを立ち上げてここで先ほどINSERTしたデータがSELECT出来るか確かめてみましょう。docker run --volumes-from strage_container --name mysql_container2 -e MYSQL_ROOT_PASSWORD=pass -d -p 3306:3306 mysql
※mysql_containerはstopしておいてください
docker exec -it mysql_container2 bash
DBとテーブルが存在するか確認します。 ![スクリーンショット 2015-12-31 20.33.00.png](https://qiita-image-store.s3.amazonaws.com/0/36871/f51d2298-f3a3-49d8-3998-6e75dc2a6e6a.png "スクリーンショット 2015-12-31 20.33.00.png")
ありましたね、最後にSELECT文を投げてみます。
SELECT * FROM user;
こちらも大丈夫そうです。
これで特定のMySQLコンテナに依存しないデータの保存ができるようになりました。
最後に
今回は異なるコンテナで1つのストレージのデータを扱う方法を試しましたが、実際同じデータを幾つものコンテナから扱っても嬉しさはそこまでありません(大量のリクエストがある時に負荷分散が出来る?)実際は同じデータを異なる環境に移行するときにコンテナベースで簡単にやりたいとか、本番と同じテストデータを用意したいという時に使いたいところです。
ただストレージコンテナはexportやsaveしてもコンテナ内には保存されないらしいですね笑
参考はここで
Dockerのbusyboxは永続コンテナと言いながらexport/saveコマンドでは持ち運びできないよ
最後が雑な感じになってしまいましたがとりあえず今日はここまで〜