🌊

Dockerでいつでも作り直せるローカルDB(mysql)作ってみた

2021/11/01に公開約4,600字6件のコメント

こんにちは!
みなさま仕事で開発する時、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の設定を書いていきます。

my.conf
[mysqld]
character-set-server=utf8
[mysql]
default-character-set=utf8
[mysqldump]
default-character-set=utf8

上記を書くことによってmysqlで日本語が文字化けしなくなります。

Dockerfile-5-7

※mysql5.7を使わない場合は不要

Dockerfile-5-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

Dockerfile-8-0
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

この内容であれば変数と設定ファイルのコピーしかしてないのでイメージをビルドしなくてもこれでいけますよ

$ docker run --name docker-mysql-5-7 -d \
  -v $PWD/db-5-7:/var/lib/mysql \
  -v $PWD/config:/etc/mysql/conf.d \
  -e MYSQL_ROOT_PASSWORD=rootpass \
  -e MYSQL_DATABASE=test \
  -e MYSQL_USER=testuser \
  -e MYSQL_PASSWORD=testpass \
  -p 23306:3306 \
  mysql:5.7.34

おお!こんなこともできるんですね!
ありがとうございます😊

MySQLを実装するのに困っていたので大変助かりました。
ありがとうございます。

ただ、日本語を入力しようとするとうまくいきません。
MySQLで日本語のデータを打ち込むとしましたが入力すると消えてしまいます。
日本語入力できるようにするにはどのようにしたらよろしいでしょうか?
よろしくお願いいたします。

本当ですね。ご指摘ありがとうございます。
解決方法を調べて、分かったらコメント致します。

解決方法わかりました。
Dockerfileに以下を追加してください。

RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29
RUN apt-get update \
    && apt-get install -y locales \
    && locale-gen ja_JP.UTF-8 \
    && echo "export LANG=ja_JP.UTF-8" >> ~/.bashrc \
    && localedef -f UTF-8 -i ja_JP ja_JP.UTF-8

MYSQL_ROOT_PASSWORDを設定している箇所の上あたりが良いです。
これで日本語入力できるようになりました。

手順はこんな感じです。

  1. docker ps で起動中のコンテナを探す。
  2. 1で出力されたコンテナの中にこの記事にしたがって作成したコンテナ(NAMESがdocker-mysql-5-7かdocker-mysql-8-0)があればCONTAINER IDをメモしておく。なければdocker ps -a を実行、CONTAINER IDをメモして手順4へ。
  3. docker stop 2でメモしたCONTAINER ID を実行し、コンテナを停止
  4. docker rm 2でメモしたCONTAINER ID でコンテナ削除
  5. dockerfileに上記を追加
  6. もう一度ビルド、起動、コンテナログイン、mysqlログイン

これで、mysqlで日本語入力ができるようになっているはずです。

ありがとうございました。日本語入力ができるようになりました。

ログインするとコメントできます