0utputab1e

MySQLをDocker(docker-compose)で立ててみた

 2020-07-06
 

前回の記事でDocker、docker-composeをインストールしました。今回はこれらを使用して、「MySQL」の仮想環境を手軽に構築してみましょう。

MySQLクライアントのインストール

MySQLサーバの役割をするDockerコンテナを立ち上げたので、

今度はホスト側(今自分のいる外側)からターミナルでログインできるように、MySQLクライアントを入れていきましょう。

aptコマンドで入れていきます。

//オプション「y」で、対話式で来る質問をすべて「yes」で実行する
$ sudo apt update && sudo apt install -y mysql-client

//インストールされた場所を確認できます
$ which mysql
/usr/bin/mysql

作業場所を作って入る

$ mkdir docker-mysql-test
$ cd docker-mysql-test

docker-composeで扱う構成を作成(+α)

以下が全体の構成図です。

$ tree .
.
├── docker
│   └── db
│       ├── data
│       ├── my.cnf
│       └── sql
│           ├── 001-create-tables.sql
│           └── init-database.sh
└── docker-compose.yml

docker/db配下にファイル、ディレクトリがありますが、

  • data: MySQLのデータの永続化(コンテナが動かなくなってもデータを残すため)
  • my.cnf: MySQLの設定ファイル
  • sql: MySQL起動時の初期化スクリプト置き場

のため、あらかじめ準備しています。

 

  • my.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

[client]
default-character-set=utf8mb4

 

  • docker/db/sql/001-create-tables.sql
    (MySQLサーバ起動時、「test_table」テーブルを、すでに存在していれば削除し、新たに作成する)
DROP DATABASE IF EXISTS test_db;

CREATE DATABASE test_db;

USE test_db;

DROP TABLE IF EXISTS test_tbl;

CREATE TABLE test_tbl (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name TEXT NOT NULL
);

INSERT INTO test_tbl (name) VALUES ("block"),("flower"),("animal");

 
ちなみに今回docker/db/sql/init-database.shは、使ってないので省略します。

docker-compose.yml(構成用コード)の作成

docker-composeでは「yaml」形式のファイルで構成を記述し、管理していきます。

以下のように、構成を組んでみます。

  • docker-compose.yml
#docker-composeの文法バージョン
version: '3'

#この区画にサービス群の定義を書いていきます
services:
  #サービス名は「db」にします
  db:
    image: mysql:5.7  #MySQL5.7のイメージを使用します
    container_name: mysql_host  #Dockerコンテナ名の命名
    #コンテナ内で使用する環境変数を書く場所です
    environment:
      MYSQL_ROOT_PASSWORD: root  #rootユーザーのパスワード
      MYSQL_DATABASE: test_db  #初期化時に作るデータベースの名前
      MYSQL_USER: docker  #dockerという名前の一般ユーザーも作ります
      MYSQL_PASSWORD: docker  #dockerユーザーのパスワード
      TZ: 'Asia/Tokyo'  #コンテナ内でタイムゾーンを日本時間にするための変数
    #コンテナ内のデータをホスト(コンテナ外)側の領域に永続化する定義です
    #書き方は「ホスト側:コンテナ側」で対応するように書きます
    volumes:
      - ./docker/db/data:/var/lib/mysql  #MySQLデータ  
      - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf  #MySQL設定ファイル
      #MySQL起動時の初期化スクリプト置き場(*.sql、*.shのファイルを使えます)
      - ./docker/db/sql:/docker-entrypoint-initdb.d
    #ポートフォワーディング(外部のポートと繋げる設定)
    #コンテナ内のMySQLはデフォルトで3306ポートで開いているので3306を指定
    #volumesと同様に「ホスト側:コンテナ側」で対応させます
    ports:
      - "3306:3306"
    #コンテナ起動時に実行するコマンド
    #コンテナ内でmysqlデーモンを指定の文字セットで起動します
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

※環境変数TZを指定してもコンテナ内のタイムゾーンが変わらない場合もあるようです。その場合はdocker-compose.ymlのvolumesブロックに以下を追加してください。

- /etc/localtime:/etc/localtime:ro

お使いのPCのローカルタイムゾーンをコンテナで読み取り専用で適用します。

ここで読みに行っている「/etc/localtime」は、PCにUbuntuをインストールしたとき自動的に設定されるものなので、あまり意識する機会がないかもです。

末尾の「ro」は、read only(読み取り専用)ボリュームとして設定するという意味なので忘れずしましょう。

 
これで以下のコマンド

$ docker-compose up --build -d

すると、MySQLコンテナが起動します。

 
以下のコマンドで起動していることを確認してみましょう。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                NAMES
13796eec43d0        mysql:5.7           "docker-entrypoint.s…"   22 minutes ago      Up 22 minutes       0.0.0.0:3306->3306/tcp, 33060/tcp    mysql_host

上記の情報から、ホスト側のhttp://0.0.0.0:3306で起動できたので、いよいよmysqlクライアントでアクセスです。

 
さっそくログインしてみます。

$ mysql -u docker --host 0.0.0.0 --port 3306 -p
Enter password: //パスワード(ここではymlファイルでの設定の通り「docker」)

 (中略)

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

mysql>

無事起動できました!

 
ついでに中にデータが入っているか確認してみます。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| ...                |
| test_db            |
+--------------------+
5 rows in set (0.00 sec)

さっきの初期化でデータベースができてます。

 
データベースの中にテーブルも確認できました。

mysql> use test_db
Database changed
mysql> show tables;
+-------------------+
| Tables_in_test_db |
+-------------------+
| test_tbl          |
+-------------------+
1 row in set (0.01 sec)

初期化スクリプトで作ったテーブルです。

 
テーブルの中のデータはどうでしょう?

mysql> desc test_tbl;
+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| id    | int(11) | NO   | PRI | NULL    | auto_increment |
| name  | text    | NO   |     | NULL    |                |
+-------+---------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> select * from test_tbl;
+----+--------+
| id | name   |
+----+--------+
|  1 | block  |
|  2 | flower |
|  3 | animal |
+----+--------+
3 rows in set (0.00 sec)

ばっちり入っていますね!

最後に

これらのコンテナはコードで構成を保管でき、Dockerとdocker-composeがあればすぐ準備できる上に、使い捨てにすることのできる環境を容易に実現でき、大変便利な仕組みです。

 
これからの開発もはかどりそうです。

 
では、また会いましょう!

 

あわせて読みたい記事

>> Homeに戻る