MySQLをDocker(docker-compose)で立ててみた
前回の記事で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があればすぐ準備できる上に、使い捨てにすることのできる環境を容易に実現でき、大変便利な仕組みです。
これからの開発もはかどりそうです。
では、また会いましょう!