Help us understand the problem. What is going on with this article?

docker-composeでMySQL5.7を起動して接続してみた

この記事は、楽にDockerコンテナでMySQLを起動してみたいDocker初心者に向けて書いています。
また、SpringBoot(FrameWork)での開発をベースにしているため、対象者が限定的になってしまうかもしれないのでご注意ください。
vertical.png

前提

  • Dockerとは何か?ざっくりと概要を知っていること
  • Docker for Mac をインストール済みであること

※Dockerをまだインストールしていない方は、下記リンクを参考にDockerを起動するところまでやりましょう
Qiita:https://qiita.com/scrummasudar/items/750aa52f4e0e747eed68

開発環境は以下の通りです。

開発環境

  • Mac OS High Sierra
  • IntelliJ IDEA
  • SpringBoot 2.0.5
  • Java8
  • Docker

そもそもDockerとは??

簡潔に述べると、 オープンソースのコンテナ管理ソフトウェアのことです。
Dockerコンテナを使うことで、アプリケーションビルド、デプロイを高速化できるとのことです。詳しい説明はスキップしますので以下をご参考にしてください。
Qiita:https://qiita.com/gold-kou/items/44860fbda1a34a001fc1
公式ドキュメント:https://docs.docker.com/

Docker Composeとは??

多様なコンテナ(docker)を定義して、起動することができるツールのこと。基本的にYAMLファイルでサービスの環境設定を行うことができます。また、一つのコマンドだけで簡単に始められるとのこと。
※DockerForMacをインストールすると自動的に付属してくるので、別途インストール不要

今回やること

  • docker-composeコマンドを使って、MySQL5.7(公式イメージ)を起動してみる
  • 起動したMySQL5.7に接続してみる
  • 準備した設定ファイル通りにDBやテーブルが初期化されているか確認する
  • 出力したクエリログをみてみる

手順

1. Dockerがインストールされているか確認する

Terminal
$ docker --version
Docker version 18.03, build c97c6d6 #インストールされていればバージョンが表示される

$ docker-compose --version
docker-compose version 1.22.0, build 8dd22a9

$ docker-machine --version
docker-machine version 0.14.0, build 9ba6da9

2. Dockerfileを作成する

ディレクトリ構成は以下のようになります。

構成
sample-project/
             ├ docker/
             |       └ mysql/
             |              ├ conf.d/
             |              |       └ my.cnf
             |              ├ initdb.d/
             |              |         ├ schema.sql
             |              |         └ testdata.sql
             |              └ Dockerfile
             └ docker-compose.yml                      

Dockerfileは、どのようなimageをビルドするかを注文する指示書のようなものです。
MySQLのversion5.7を使用するため、公式イメージをビルドするように以下のように記述します。

Dockerfile
FROM mysql:5.7
RUN touch /var/log/mysql/mysqld.log # 指定の場所にログを記録するファイルを作る

3. docker-compose.ymlを作成する

このYAMLファイルでは、複数のサービスの設定が可能です。具体的には各々のサービスのポート番号を指定したり、記憶領域(volume)の設定をすることができます。

docker-compose.yml
version: '3.3'
services:
  db:
    build: ./docker/mysql
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: sample_db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: rootpassword
    ports:
      - "3314:3306"
    volumes:
      - ./docker/mysql/initdb.d:/docker-entrypoint-initdb.d
      - ./docker/mysql/conf.d:/etc/mysql/conf.d
      - ./log/mysql:/var/log/mysql

4. my.cnfを作成する

ここでは、MySQLの設定をすることができます。

my.cnf
[mysqld]
character-set-server=utf8mb4       # mysqlサーバー側が使用する文字コード
explicit-defaults-for-timestamp=1   # テーブルにTimeStamp型のカラムをもつ場合、推奨
general-log=1                   # 実行したクエリの全ての履歴が記録される(defaultではOFFになっているらしい)
general-log-file=/var/log/mysql/mysqld.log # ログの出力先

[client]
default-character-set=utf8mb4               # mysqlのクライアント側が使用する文字コード

5. テーブル定義ファイルを作成する

テーブルの作成を初期化処理として行いたいので、DDLファイルを用意します。

schema.sql
CREATE TABLE users (
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(32) NOT NULL,
    email VARCHAR(32) NOT NULL,
    PRIMARY KEY (id)
);

6. テストデータを作成する

あらかじめテーブルにデータを準備することができます。

testdata.sql
INSERT INTO users (id,name,email) VALUES (1, 'TOM','xxxx@mail.co.jp');

7. docker-composeコマンドを実行する

以下コマンドはプロジェクトのルートディレクトリで実行します。

Terminal
$ docker-compose up -d # コンテナを作成しスタートする
Creating network "sample-project_default" with the default driver
Creating sample-project_db_1 ... done

$ docker-compose ps # 存在するコンテナのリストを表示する
        Name                   Command           State           Ports         
--------------------------------------------------------------------------------
sample-project_db_1    docker-entrypoint.sh     Up      0.0.0.0:3314->3306/tcp
                       mysqld                           , 33060/tcp  

↓その他コマンド↓
$ docker-compose stop # サービスを停止させる
$ docker-compose down # コンテナの停止、削除、さらにネットワーク、記憶領域を全て削除

8. 起動したMySQLに接続してみる

では、早速docker-composeで立ち上げたMysqlに接続してみます。

Terminal
$ docker exec -it sample-project_db_1 bash # sample-project_db_1というコンテナに入りコマンドを実行
# mysql -u user -p # ログインする
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
mysql> use sample_db;
Database changed

Database changed
mysql> show tables; # テーブルが作られているか確認する
+---------------------+
| Tables_in_sample_db |
+---------------------+
| users               |
+---------------------+
1 row in set (0.00 sec)

mysql> select * from users; # 仕込んだデータが入っているか確認する
+----+------+-----------------+
| id | name | email           |
+----+------+-----------------+
|  1 | TOM  | xxxx@mail.co.jp |
+----+------+-----------------+
1 row in set (0.00 sec)

このままだとコンテナ内からMysqlに接続しているだけなので、接続方法を換えて確認します。
ホスト名、ポートを指定してログインします。(指定しない場合デフォルトのポート3306に繋ぐようです)

Terminal
$ mysql --host 127.0.0.1 --port 3314 -u user -p 
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g
・
・
mysql>

9. ログを確認する

先ほど設定した場所にファイルができていることを確認します。

ディレクトリ構成
sample-project/
              ├ docker
              ├ log/
              |    └ mysql/
              ├ src       └ mysqld.log
              |
              └ docker-compose.yml

ファイルの中身はこんな感じになりました。

mysqld.log
mysqld, Version: 5.7.23-log (MySQL Community Server (GPL)). started with:
Tcp port: 0  Unix socket: /var/run/mysqld/mysqld.sock
Time                 Id Command    Argument
2018-10-13T11:38:04.918533Z     1 Query CREATE DATABASE mysql;
2018-10-13T11:38:04.919437Z     1 Query USE mysql;
                 ・
                 ・
            以下割愛

今回、全てのクエリログを出す設定にしているため、ファイルのサイズはなかなか大きいようです(6.71MB)

感想

コンテナの概念への理解度がまだまだ低いのでなんとなくやってる感がありますが、ローカルでMySQLをインストールして諸々いじくるよりも楽で、ローカル環境を汚さないので、これからどんどん使っていこうと思いました。
今回紹介していませんが、Springbootで開発したアプリケーションから接続する手順も今後シェアできたらいいなと思います。

その他の参考ページ

LazyHippos
現在はデジタルマーケティングのお仕事をしています。 以前は、ウェブ広告系サービスのトラブルシューティングしていました。 東京ではBackend developerやってました。 Java, JavaScript, MySQL, Spring Boot などを使用した開発経験ありです。
https://surfhippos.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした