Dockerの公式MySQLを触ってみた(初心者)

  • 6
    いいね
  • 2
    コメント

ゴール

  • マルチバイト対応(日本語が化けないようにする)
  • Dockerコンテナを消してもデータを消えないようにする
  • おまけ(docker-compose化)※[追記]コメントで指摘頂きましたが、composeを使えばそもそもファイルの置き換えは不要ですね!

マルチバイト文字対応

デフォルトの文字コードだと日本語が文字化けしてしまうので、UTF-8化してみることにする。
Dockerの公式MySQLは日本語が文字化けするのでutf8かutf8mb4にしたい
に詳しく書かれているので詳細は端折ることにする。

手順

文字コードを設定する、mysqld.cnfを公式のDocker Imageから抜き出してコンテナを設定ファイルを書き換えて日本語化する

Docker Image作成

docker run -d --name test -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=testdb mysql:8.0.0

testというコンテナ名で作成。作成したコンテナは設定ファイルを取り出すためだけのもので、すぐに削除するので名前はなんでも良い。

※バージョンが異なると、設定ファイルの置き場所が変わることがあるので、
今回は、2017/2/21時点で最新の8.0.0のイメージを利用することにする。

mysql:8.0.0 の部分のバージョンタグを削ってmysqlとすると最新のバージョンがDLされる。

Docker containerから元となるmysqld.cnfを抜き出す

mkdir mysql.conf.d
docker cp test:/etc/mysql/mysql.conf.d/mysqld.cnf ./mysql.conf.d/

設定ファイルの置き場所

/path/to/
└── mysql.conf.d
    └── mysqld.cnf

参考ページのDockerイメージとバーションが異なったみたいで、
設定ファイルの場所が変わっていたので、
docker exec test -it /bin/bash
を使ってコンテナにsshして設定ファイルの場所を調べました。  ※testはコンテナ名

文字コードをUTF-8に書き換え

mysqld.cnf
(省略)
[mysqld]
# 以下の1行を追加
character-set-server = utf8
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
datadir     = /var/lib/mysql
#log-error  = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address   = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# 以下の2行を追加
[client]
default-character-set=utf8

※mysql clientの文字コードもutf-8に変更

元となるDockerコンテナを削除

docker stop test
docker rm test

コンテナ再作成&起動

docker run -d --name mydb -v /path/to/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=db mysql:8.0.0

# コンテナ名:mydb
# rootのパスワード:password
# スキーマ名:db
# ポイント: -vオプションでホストの任意のパスをコンテナの任意のパスにマウント

/path/to/の場所は適宜書き換えください。

文字コードの確認

コンテナに接続して文字コードを確認

$ docker exec -it mydb bash

# dockerコンテナ側での作業
# mysql -u root -ppassword
mysql> show variables like "chara%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

これで、文字コードの変更は完了。

Dockerコンテナを消してもデータを消えないようにする

データvolumeの場所を調べる

$ docker inspect mydb


(省略)
            {
                "Type": "volume",
                "Name": "b62ce9b9b35e964ad1f34af9dab41522050735b0f174d226a587e47a5f322e25",
                "Source": "/var/lib/docker/volumes/b62ce9b9b35e964ad1f34af9dab41522050735b0f174d226a587e47a5f322e25/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
(省略)

/var/lib/mysql がMySQLのデータボリュームだということがわかる。

/path/to/
├── mysql.conf.d
└── volume     // ←ホスト側にvolumeディレクトリを作成
$ docker run -d --name mydb -v /path/to/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /path/to/volume/:/var/lib/mysql/ -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=db mysql:8.0.0

# -v /path/to/volume/:/var/lib/mysql オプションを追加

-v フラグは複数指定することが可能で、複数の Data Volume をマウントすることができる。

サンプルデータを登録

$ docker exec -it mydb bash

#以下コンテナ側の作業
# mysql -u root -ppassword

mysql>

CREATE SCHEMA IF NOT EXISTS `docker_scheme` DEFAULT 
CHARACTER SET utf8 ;
USE `docker_scheme` ;

DROP TABLE IF EXISTS `docker_scheme`.`students` ;

CREATE TABLE IF NOT EXISTS `docker_scheme`.`students` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(32) NOT NULL DEFAULT '',
  `age` INT NOT NULL DEFAULT 20,
  PRIMARY KEY (`id`),
  INDEX `AGE` (`age` ASC))
ENGINE = InnoDB;

INSERT INTO students(`name`, `age`) VALUES('Tanaka', 21);

コンテナを削除

# 停止&削除
docker stop mydb
docker rm mydb

# プロセスが存在しないことを確認
docker ps -a

Dockerコンテナ再作成して、データが保持されているかを確認

上記のdocker runを再実行する

# mysql -u root -ppassword

mysql> use docker_scheme;

mysql> select * from students;
+----+--------+-----+
| id | name   | age |
+----+--------+-----+
|  1 | Tanaka |  21 |
+----+--------+-----+
1 row in set (0.00 sec)

コンテナを停止してもデータが保持されていることを確認

おまけ(Docker Compose化)

docker runするのにオプションが多くて面倒なので
docker-compose.yamlに記述して簡略化する。

docker-compose.yaml
# MySQLコンテナ
mysql:
  image: mysql:8.0.0
  container_name: mydb
  volumes:
    - "/path/to/mysql.conf.d/:/etc/mysql/mysql.conf.d/"
    - "/path/to/volume/:/var/lib/mysql/"
  environment:
    - MYSQL_ROOT_PASSWORD=password

あとは、
docker-compose up -d

すればコンテナが起動する