ログってなんぼ

エンジニアのメモです

Dockerの公式MySQLコンテナで色々遊んで親しんでみた

f:id:Okisanjp:20161228185035p:plain

https://hub.docker.com/_/mysql/

2016年ももう終わりですねえ。

今日で今年の業務は終了なので、最後はDockerの公式MySQLコンテナとじゃれあいたいと思います。

まずは普通に起動してみます

$ docker run --name mysql-test -e MYSQL_ROOT_PASSWORD=passw0rd -d mysql:5.7
9c145273dea014107babf42790059666bef0d4535dd4486a5ae4ea7b00c9e436

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
9c145273dea0        mysql:5.7           "docker-entrypoint.sh"   5 seconds ago       Up 6 seconds        3306/tcp            mysql-test

$ docker exec -it mysql-test /bin/bash

root@9c145273dea0:/# mysql -uroot -ppassw0rd
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.16 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

確認できたら一旦消しちゃいます

$ docker stop mysql-test && docker rm mysql-test
mysql-test
mysql-test

環境変数を与えて起動する

MYSQL_ROOT_PASSWORDの他にも渡せる環境変数があるので試します

MYSQL_DATABASE

コンテナ起動時に指定された名前のDBを作成します

MYSQL_USER, MYSQL_PASSWORD

MYSQL_DATABASEで指定されたDBに対する全権限を持つユーザーとパスワードを作成します

docker run --name mysql-test \
-e MYSQL_ROOT_PASSWORD=passw0rd \
-e MYSQL_DATABASE=testdb \
-e MYSQL_USER=okisanjp \
-e MYSQL_PASSWORD=okisanjp-pw \
-d mysql:5.7

起動コマンドはこんな感じになります

起動~確認
$ docker run --name mysql-test \
-e MYSQL_ROOT_PASSWORD=passw0rd \
-e MYSQL_DATABASE=testdb \
-e MYSQL_USER=okisanjp \
-e MYSQL_PASSWORD=okisanjp-pw \
-d mysql:5.7
699c3d2a663a671777aedbaa146ddf7353f32363f00cbf043566b79d92cfab17
$ docker exec -it mysql-test /bin/bash
root@07cbf9475fd6:/#

root@07cbf9475fd6:/# mysql -uroot -ppassw0rd
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.16 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
ユーザーができているか確認
mysql> show grants for okisanjp;
+------------------------------------------------------+
| Grants for okisanjp@%                                |
+------------------------------------------------------+
| GRANT USAGE ON *.* TO 'okisanjp'@'%'                 |
| GRANT ALL PRIVILEGES ON `testdb`.* TO 'okisanjp'@'%' |
+------------------------------------------------------+
2 rows in set (0.00 sec)

mysql>
作成されたユーザーでログインしてDBを操作できるか確認
root@07cbf9475fd6:/# mysql -uokisanjp -pokisanjp-pw
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.16 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| testdb             |
+--------------------+
2 rows in set (0.00 sec)

mysql> create table testdb.user(id int, name varchar(30));
Query OK, 0 rows affected (0.00 sec)

mysql> insert into testdb.user values (1, "okisanjp");
Query OK, 1 row affected (0.00 sec)

mysql> select * from testdb.user;
+------+----------+
| id   | name     |
+------+----------+
|    1 | okisanjp |
+------+----------+
1 row in set (0.00 sec)

文字コード関連

環境変数ではないですが文字コードの指定などについて

まず現在の文字コードを確認

mysql> show variables like "character%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

mysql> show table status from testdb\G
*************************** 1. row ***************************
           Name: user
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 1
 Avg_row_length: 16384
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2016-12-28 07:47:49
    Update_time: 2016-12-28 07:49:28
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.00 sec)

utf8mb4へ変更してみる

🍣🍺の件もあるのでutf8mb4にしてみます

一旦消します

$ docker stop mysql-test && docker rm mysql-test
mysql-test
mysql-test

こんな感じの起動オプションになります

docker run --name mysql-test \
-e MYSQL_ROOT_PASSWORD=passw0rd \
-e MYSQL_DATABASE=testdb \
-e MYSQL_USER=okisanjp \
-e MYSQL_PASSWORD=okisanjp-pw \
-d mysql:5.7 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
起動してテスト
$ docker run --name mysql-test \
> -e MYSQL_ROOT_PASSWORD=passw0rd \
> -e MYSQL_DATABASE=testdb \
> -e MYSQL_USER=okisanjp \
> -e MYSQL_PASSWORD=okisanjp-pw \
> -d mysql:5.7 \
> --character-set-server=utf8mb4 \
> --collation-server=utf8mb4_unicode_ci
d370b7fffa25ac4e8ceea5cc656a5717fbff5d5e69d74d65f9de71f94525d84a
$ docker exec -it mysql-test /bin/bash
root@d370b7fffa25:/# mysql -uroot -ppassw0rd
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.16 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
文字コードを確認してみます
mysql> show variables like "character%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

mysql> create table testdb.user(id int, name varchar(30));
Query OK, 0 rows affected (0.00 sec)

mysql> insert into testdb.user values (1, "okisanjp");
Query OK, 1 row affected (0.00 sec)

mysql> show table status from testdb\G
*************************** 1. row ***************************
           Name: user
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 1
 Avg_row_length: 16384
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2016-12-28 08:03:57
    Update_time: 2016-12-28 08:04:02
     Check_time: NULL
      Collation: utf8mb4_unicode_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.00 sec)

mysql>

設定ファイルによる起動

ホストマシンに置いた設定ファイルをマウントして起動してみます

今回は、~/workspace/docker-official-mysql-practice/mysql_settings/okisanjp.cnfという感じでファイルを作成しました

-vオプションで~/workspace/docker-official-mysql-practice/mysql_settingsディレクトリをコンテナの/etc/mysql/conf.dとしてマウントします

okisanjp.cnf

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci

[mysql]
default-character-set = utf8mb4
show-warnings

またまた一旦消します

$ docker stop mysql-test && docker rm mysql-test
mysql-test
mysql-test

起動オプションはこんな感じ

docker run --name mysql-test \
-v ~/workspace/docker-official-mysql-practice/mysql_settings:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=passw0rd \
-e MYSQL_DATABASE=testdb \
-e MYSQL_USER=okisanjp \
-e MYSQL_PASSWORD=okisanjp-pw \
-d mysql:5.7
確認

コンテナに入ってmysqlクライアントで接続するまでは省きます

mysql> show variables like "character%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

データの永続化

データディレクトリをホストマシンの任意のディレクトリにしてデータを永続化します

$ tree
.
├── mysql_data
└── mysql_settings
    └── okisanjp.cnf

mysql_dataディレクトリを空で作っておきます

起動

一旦けしm(ry

$ docker stop mysql-test && docker rm mysql-test
mysql-test
mysql-test

起動します -vが増えました

$ docker run --name mysql-test \
-v ~/workspace/docker-official-mysql-practice/mysql_data:/var/lib/mysql \
-v ~/workspace/docker-official-mysql-practice/mysql_settings:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=passw0rd \
-e MYSQL_DATABASE=testdb \
-e MYSQL_USER=okisanjp \
-e MYSQL_PASSWORD=okisanjp-pw \
-d mysql:5.7

ホストマシンのディレクトリを再度確認

$ tree -d
.
├── mysql_data
│   ├── mysql
│   ├── performance_schema
│   ├── sys
│   └── testdb
└── mysql_settings

見慣れたディレクトリができて、中にMySQLデータのファイルがいっぱい作成されました

永続化の確認

コンテナに入ってデータを登録
$ docker exec -it mysql-test /bin/bash

もう面倒なのでワンライナーでテーブル作ってデータを突っ込んでSELECTします

root@f680ba29ed11:/# mysql -uroot -ppassw0rd -e'create table testdb.user(id int, name varchar(30));insert into testdb.user values (1, "okisanjp");select * from testdb.user;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------+----------+
| id   | name     |
+------+----------+
|    1 | okisanjp |
+------+----------+
コンテナを消します

何回消すねん

$ docker stop mysql-test && docker rm mysql-test
mysql-test
mysql-test

再度起動してSELECTしてみます

データが永続化されているはずなので起動オプションからDB作成とユーザー作成を省きます

$ docker run --name mysql-test -v ~/workspace/docker-official-mysql-practice/mysql_data:/var/lib/mysql -v ~/workspace/docker-official-mysql-practice/mysql_settings:/etc/mysql/conf.d -d mysql:5.7
2f0b7127ce939a14adc71b28797c1737e062ed78c318a749cc8ddd627c2bf96c
$ docker exec -it mysql-test /bin/bash

root@2f0b7127ce93:/# mysql -uroot -ppassw0rd -e'select * from testdb.user;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------+----------+
| id   | name     |
+------+----------+
|    1 | okisanjp |
+------+----------+

mysql> select * from testdb.user;
+------+----------+
| id   | name     |
+------+----------+
|    1 | okisanjp |
+------+----------+
1 row in set (0.01 sec)

mysql> select user from mysql.user;
+----------+
| user     |
+----------+
| okisanjp |
| root     |
+----------+
2 rows in set (0.01 sec)

OK(∩´∀`)∩ワーイ

Dockerfileやdocker-composeについて

実際にはMySQLコンテナだけ立ち上げて何かすることは殆どないと思うのでDockerfileとdocker-compose.ymlで環境を作ることになりますね

okisanjp.hatenablog.jp

大したこと書けてませんが、もし参考になったらウレシスです

その他詳しくは

https://hub.docker.com/_/mysql/

こちらにて。

ごあいさつ

当Blogにアクセスしてくださった皆様ありがとうございました。

来年はマネジメント方面の仕事もやってみたいと思っているので、2017年はインフラやプログラミングに限らずインターネット業界での仕事に関連するメモが色々と書けたら良いと思っています。

来年もよろしくお願いします