Dockerで予め欲しいデータをつっこんだMySQLをこしらえる(Mac用)
MySQLいっぱい生み出して使い分けがしたかったので調べた。
今はまだコンテナが死ぬとデータも死ぬ仕組みなので、主にDaoあたりのユニットテストで一時的なデータ入れるためのDBとして使っておる。
うまくいくまで悩んだりもしたので、やり方だけメモしておく!
ちなみにMac OS X El CapitanでVirtualBox使って動かしているよ!!
✬やってみること
- MySQLをDocker上で動かす
hoge
データベースを作るhoge.users
テーブルを作るduke
ユーザを作り、hoge
に実行権限を付与する
✬インストール
✏VirtualBox, Docker Machine, Docker Toolboxをインストール
$ brew cask install virtualbox $ brew install docker-machine $ brew cask install dockertoolbox
✬DockerfileとSQLの用意
✏サンプル
こんな感じ。
#Dockerfile # FROM コマンドでDocker公式のMySQLイメージを使える(コロン以降がバージョン) FROM mysql:5.7 # RUN コマンドでDocker側で実行するシェルのコマンドを書ける # MySQLの設定をこんな感じで追加しておく RUN { \ echo '[mysqld]'; \ echo 'character-set-server = utf8'; \ } > /etc/mysql/conf.d/charset.cnf # COPY コマンドで自分のマシンからDockerの/docker-entrypoint-initdb.d/下にprepare.sqlをコピーする # /docker-entrypoint-initdb.d/ 下にあるSQLは全部勝手に実行してくれる!!! COPY prepare.sql /docker-entrypoint-initdb.d/prepare.sql
--prepare.sql -- これはいらないかも... DROP DATABASE IF EXISTS hoge; DROP DATABASE IF EXISTS fuga; -- データベースを作る CREATE DATABASE hoge; -- dukeユーザをつくってよしなに権限をつける GRANT ALL PRIVILEGES ON hoge.* TO 'duke'@'localhost'; -- テーブルを作る (実際はちゃんとしたDDLを用意する) CREATE TABLE `hoge`.`users` ~ ;
要は、実行したいSQL(登録したいデータ)入りファイル/docker-entrypoint-initdb.d/
にコピーすればよい!
複数ファイルあっても、コピーした分全部実行される。あと、ダンプファイルとかそのまま使えるのでべんり!
✏応用編(正しいかは分からないけどこれで解決できた)
- SQLが複数ファイルにまたがっているが、実行順を制御したいとき(外部キーがあるとか...)
/docker-entrypoint-initdb.d/
にコピー後のファイル名を、ls
コマンドで上から実行順に並ぶよう工夫する。
つまり、a.1番目のファイル.sql
、b.2番目のファイル.sql
、...みたいにすればその順番に実行できるよ〜。強引。 - 操作対象のデータベースを変更したいとき(データベース指定のないSQL文を実行するとか...)
USE hoge
とか書いたファイルを作って、意図した通りの順序で実行する。
✬初回セットアップでやること
✏test
という名前でDockerホストを作成
IPアドレスの指定が不要な場合は、--virtualbox-hostonly-cidr "192.168.99.99/24"
の部分は書かなくてもよい。自動で採番されるので大丈夫。
指定したい場合は例みたいにして、CIDR形式で書こう!
$ docker-machine create --driver virtualbox --virtualbox-hostonly-cidr "192.168.99.99/24" test
✏test
ホストを起動
restart
コマンドやstop
コマンドもある。
$ docker-machine start test
✏環境変数を適用
$ eval "$(docker-machine env test)"
✏Dockerイメージをビルド
latest
はイメージのバージョンに該当する。
$ docker build -t test:latest .
✬起動の度にやること
✏test
ホストを起動
$ docker-machine start test
✏環境変数を適用
$ eval "$(docker-machine env test)"
✏起動中のコンテナをすべて停止、削除
関係ないものも停止しちゃうので注意。当然だけどまだ何も起動してないならやらなくてもよい。
$ docker stop $(docker ps -aq) $ docker rm $(docker ps -aq)
✏test-mysql
という名前でコンテナを立ち上げ (ポート番号はお好きに変更してね)
次の例だと、ローカルからポート3307のmysqlに繋ごうとすればよい。Dockerがポートフォワードしてくれて3306に繋げ変えてくれるらしい・・・
$ docker run --name test-mysql -p 3307:3306 -v ~/docker/mysql/conf.d:/etc/mysql/conf.d -e MYSQL_USER=duke -e MYSQL_PASSWORD=password -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=test -d test:latest
はい出来た!これでOK!!!
prepare.sql
に書いたSQLたちが実行された状態でMySQLが誕生するよ〜。
接続できるか確認してみよう!
$ mysql -h$(docker-machine ip test) -P3307 -uduke -p
ちなみに立ち上げで使うコマンドはシェルスクリプトか何かにしてしまえばもっとラクラクになる。
#!/bin/sh # ホストを起動する docker-machine start test # 環境変数を適用する eval "$(docker-machine env test)" # 起動中のコンテナをすべて停止、削除する(関係ないものも停止するので注意) docker stop $(docker ps -aq) docker rm $(docker ps -aq) # コンテナを立ち上げる docker run --name test-mysql -p 3307:3306 -v ~/docker/mysql/conf.d:/etc/mysql/conf.d -e MYSQL_USER=duke -e MYSQL_PASSWORD=password -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=test -d test:latest
✬その他よく使うコマンド(の一部)
✏実行中のコンテナを確認
$ docker ps
✏ログ確認 (立ち上がらない時とかはこれをチェック!)
$ docker logs --follow test-mysql
以上!Docker入門出来て嬉しいな!
強引なやり方を採用しているところは、もっとよい術があれば是非教えて下さい!
参考ページ: