Dockerでいつでも作り直せるローカルDB(mysql)作ってみた
こんにちは!
みなさま仕事で開発する時、DBはどうしていますか? 各自がローカルのDBを用意していますか?それとも共用のDBを使っていますか?
私は普段仕事で開発するときは検証用のDBに繋いでいることが多いです。本番とは別のDBが用意されていて開発時はそのDBをみんなで使う感じです。みんなが同じDBを使うので条件が揃うという意味では良いのですが、やはり他の人も使うものなので気軽に壊したりはできないわけです。
そんな時にローカルで壊してもすぐに作り直せるDBがあれば便利だと思い、今回Dockerを使って作成してみました。
ディレクトリ構成
私はmysql8.0とmysql5.7の両方を作成したので以下のような構成となりました。
root/
├─ Dockerfile-5-7
├─ Dockerfile-8-0
├─ db-5-7
├─ db-8-0
├─ config
└─ my.conf
どちらか一つだけで良い場合は以下のようになりますかね。
root/
├─ Dockerfile
├─ db
├─ config
└─ my.conf
my.conf作成
config配下にmy.confを作成し、mysqlの設定を書いていきます。
[mysqld]
character-set-server=utf8
[mysql]
default-character-set=utf8
[mysqldump]
default-character-set=utf8
上記を書くことによってmysqlで日本語が文字化けしなくなります。
Dockerfile-5-7
※mysql5.7を使わない場合は不要
FROM mysql:5.7.34
ENV MYSQL_ROOT_PASSWORD rootpass
ENV MYSQL_DATABASE test
ENV MYSQL_USER testuser
ENV MYSQL_PASSWORD testpass
COPY ./config/my.conf /etc/mysql/conf.d/my.cnf
# docker build -t docker-mysql-5-7:1 -f Dockerfile-5-7 .
# docker run --name docker-mysql-5-7 -d -v $PWD/db-5-7:/var/lib/mysql -p 23306:3306 docker-mysql-5-7:1
# docker exec -it docker-mysql-5-7 bash
- mysql:5.7.34のdocker imageを使用。
- 環境変数を設定。
これらがmysqlにログインする時のuserやpasswordになります。 - 先ほど作成したmy.confを/etc/mysql/conf.d/配下にコピー。
コメントアウトされている下の3行はこれから実行するコマンドです。
build
docker build -t docker-mysql-5-7:1 -f Dockerfile-5-7 .
-f
を使って使用するDockerfileを指定しています。何も指定しないとDockerfileという名前のファイルを探します。今回はDockerfile-5-7というファイルを使用するので指定。
起動
docker run --name docker-mysql-5-7 -d -v $PWD/db-5-7:/var/lib/mysql -p 23306:3306 docker-mysql-5-7:1
-
--name
でコンテナの名前を指定。 -
-v
でボリュームを指定。自分のPCのこのコマンドを実行した箇所のdb-5-7ディレクトリと/var/lib/mysqlが同期します。 -
-p
でポートを指定。-p 23306:3306
だと自分のPCの23306番ポートにアクセスするとdockerコンテナの3306番ポートにアクセスするようになります。 - 最後の
docker-mysql-5-7:1
は先ほど作成したdocker imageを使用。
dockerコンテナログイン & mysqlログイン
docker exec -it docker-mysql-5-7 bash
上記コマンドでdockerコンテナにログイン。
mysql -u testuser -p
testpass
これでmysqlにログイン完了です。
Dockerfile-8-0
※mysql8.0を使わない場合は不要
普段myql5.7を使っていていきなり8.0に変えると接続できないこともあるようです。
参考: https://www.chuken-engineer.com/entry/2020/09/04/074216
FROM mysql:8.0
ENV MYSQL_ROOT_PASSWORD rootpass
ENV MYSQL_DATABASE test
ENV MYSQL_USER testuser
ENV MYSQL_PASSWORD testpass
COPY ./config/my.conf /etc/mysql/conf.d/my.cnf
# docker build -t docker-mysql-8-0:1 -f Dockerfile-8-0 .
# docker run --name docker-mysql-8-0 -d -v $PWD/db-8-0:/var/lib/mysql -p 13306:3306 docker-mysql-8-0:1
# docker exec -it docker-mysql-8-0 bash
- mysql:8.0のdocker imageを使用。
- 環境変数を設定。
これらがmysqlにログインする時のuserやpasswordになります。 - 先ほど作成したmy.confを/etc/mysql/conf.d/配下にコピー。
コメントアウトされている下の3行はこれから実行するコマンドです。
build
docker build -t docker-mysql-8-0:1 -f Dockerfile-8-0 .
-f
を使って使用するDockerfileを指定しています。何も指定しないとDockerfileという名前のファイルを探します。今回はDockerfile-5-7というファイルを使用するので指定。
起動
docker run --name docker-mysql-8-0 -d -v $PWD/db-8-0:/var/lib/mysql -p 13306:3306 docker-mysql-8-0:1
-
--name
でコンテナの名前を指定。 -
-v
でボリュームを指定。自分のPCのこのコマンドを実行した箇所のdb-8-0ディレクトリと/var/lib/mysqlが同期します。 -
-p
でポートを指定。-p 13306:3306
だと自分のPCの13306番ポートにアクセスするとdockerコンテナの3306番ポートにアクセスするようになります。 - 最後の
docker-mysql-8-0:1
は先ほど作成したdocker imageを使用。
dockerコンテナログイン & mysqlログイン
docker exec -it docker-mysql-8-0 bash
上記コマンドでdockerコンテナにログイン。
mysql -u testuser -p
testpass
これでmysqlにログイン完了です。
データコピー
mysqlにログインできたかと思いますが、今のままではデータがありません。
mysqldumpを使って共用のDBからデータをコピーします。
下記コマンドを実行します。
mysqldump -u ユーザー名 -p -h 共用DBのホスト名 データベース名 > 〇〇.sql
sqlファイルの名前はなんでも良いですが、今回は{プロジェクト名 + 日付}.sqlにしました。
続いて作成したsqlファイルをコンテナに送ります。
方法は簡単で下記コマンドを実行するだけです。
mysql5.7の場合
docker cp {プロジェクト名 + 日付}.sql docker-mysql-5-7:/tmp/
mysql8.0の場合
docker cp {プロジェクト名 + 日付}.sql docker-mysql-8-0:/tmp/
※ 以降はmysql5.7のコマンドのみ表記します。mysql8.0をお使いの方は適宜書き換えてください。
これでコンテナのtmpディレクトリにsqlファイルが送られました。
今度はこのsqlファイルを使ってdockerで作成したDBにデータを入れていきます。
まずdockerコンテナにログインします。
docker exec -it docker-mysql-5-7 bash
そして以下のコマンドを実行
mysql -u testuser -p test < tmp/{プロジェクト名 + 日付}.sql
これでDockerで作成したDBにデータがコピーされました。
アプリから接続
Dockerで作成したDBにアプリから接続するようにします。
こちらも方法は簡単です。おそらくhost名やuser, パスワードなどを指定している箇所があるかと思います。そこを以下のように変えるだけです。mysql8.0を使っていて上述の方法で起動した方はportが13306ですね。
host: '127.0.0.1',
user: 'testuser',
password: 'testpass',
database: 'test',
port: 23306,
まとめ
以上です。Dockerでローカルで使えるDBを作成することができました。これを使えばデータを消してしまうかもしれないコマンドなども臆することなく実行できますね。もし失敗してもまた作り直せば良いですので。
注意点としてはPCの電源を切るとコンテナも停止するので、次に起動した時にも使いたい場合はもう一度コンテナを起動しないといけないです。データは残っているので安心してください。
docker ps -a
でmysqlのコンテナIDを探し、 docker start コンテナID
で起動できます。
Discussion
この内容であれば変数と設定ファイルのコピーしかしてないのでイメージをビルドしなくてもこれでいけますよ
おお!こんなこともできるんですね!
ありがとうございます😊
MySQLを実装するのに困っていたので大変助かりました。
ありがとうございます。
ただ、日本語を入力しようとするとうまくいきません。
MySQLで日本語のデータを打ち込むとしましたが入力すると消えてしまいます。
日本語入力できるようにするにはどのようにしたらよろしいでしょうか?
よろしくお願いいたします。
本当ですね。ご指摘ありがとうございます。
解決方法を調べて、分かったらコメント致します。
解決方法わかりました。
Dockerfileに以下を追加してください。
MYSQL_ROOT_PASSWORDを設定している箇所の上あたりが良いです。
これで日本語入力できるようになりました。
手順はこんな感じです。
docker ps
で起動中のコンテナを探す。docker ps -a
を実行、CONTAINER IDをメモして手順4へ。docker stop 2でメモしたCONTAINER ID
を実行し、コンテナを停止docker rm 2でメモしたCONTAINER ID
でコンテナ削除これで、mysqlで日本語入力ができるようになっているはずです。
ありがとうございました。日本語入力ができるようになりました。