B-Teck!

お仕事からゲームまで幅広く

【MySQL/Docker】docker-composeでMySQL5.7のイメージを作成して接続する備忘録

参考にした記事

本記事はこれらの記事を参考に自分でDBを構築してみた作業メモとなります。
不明点があれば、下記の記事をご覧いただくことで解決するかもしれません。

環境

macOS Mojave 10.14.6  
Docker version 19.03.5, build 633a0ea  
docker-compose version 1.25.4, build 8d51620a  

最終的なプロジェクトのディレクトリ構成例(MySQLの場合)

今回は下記のようなプロジェクトを作成することを目標とします

sample-project/
             ├ docker/
             |       └ mysql/
             |              ├ conf.d/
             |              |       └ my.cnf
             |              ├ initdb.d/
             |              |       ├ data.csv
             |              |       ├ import.sh
             |              |       └ ddl.sql
             |              └ Dockerfile
             └ docker-compose.yml            

インストール

  • docker for macをインストール
$ brew cask install docker
$ brew install docker-compose

Dockerfileを作成する

Dockerfileにimageの内容を記述することでそのとおりのimageが作成される
MySQL 5.7のimageを作成するには下記のように記載する

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

docker-compose.ymlを作成する

プロジェクト内に含んでいるServiceのportやvolumeなどの設定を行うことができる。

version: '3.3'
services:
  db:
    build: ./docker/mysql
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: sampledb
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: mysql
    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

my.cnf(MySQLの設定ファイル)を作成する

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

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

initdb.d配下配置したスクリプトでDBの初期化を行う

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

Initializing a fresh instance When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data.

公式イメージは /docker-entrypoint-initdb.dに.sqlや.shを置いておけば初回起動時に実行 してくれる。
今回はdocker-compose.ymlのvolumeに ./docker/mysql/initdb.d:/docker-entrypoint-initdb.d を記載しているので、 /docker/mysql/initdb.d にリソースを配置する。

初期化処理でテーブル作成

  • 初期化用のDDLを配置
mysql/initdb.d/
            └ ddl.sql
  • ddl.sql
CREATE TABLE users (
    name VARCHAR(32) NOT NULL,
    email VARCHAR(32) NOT NULL
);

初期化処理でテストデータimport

  • 読み込み対象のcsv等と、それをimportする.shを配置
mysql/initdb.d/
            ├ data.csv
            └ import.sh
  • data.csv
exam taro,xxxx@mail.co.jp
  • import.sh
mysql -uroot -pmysql --local-infile sampledb -e "LOAD DATA LOCAL INFILE '/docker-entrypoint-initdb.d/data.csv' INTO TABLE users FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n'"

プロジェクトのルートでdocker-composeコマンドを実行

今回の場合は sample-project/ 配下で実行します。

$ docker-compose up # コンテナを作成しスタートする
$ docker-compose ps # コンテナの状態を確認

各種コマンドメモ

  • up
    docker-compose.ymlで定義したサービスを開始または再起動する
  • run
    service名を指定して特定のサービスのコンテナと依存するコンテナを起動する
  • start
    既に作成済みのコンテナを再起動する
  • stop
    サービスを停止させる
  • down
    コンテナの停止、削除、さらにネットワーク、記憶領域を全て削除
  • ps
    存在するコンテナのリストを表示する

起動したMySQLに接続

コンテナ内からDBにアクセスできることを確認

$ docker exec -it sample-project_db_1 bash # sample-project_db_1コンテナでコマンドを実行
# mysql -u user -ppassword sampledb # 作成したmysqlにログイン
mysql> show tables; # テーブルが作られているか確認する
mysql> select * from users; # 仕込んだデータが入っているか確認する

ホスト名 ポートを指定してログイン

  • docker-compose ps でIP、portを確認
$ 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              
  • 確認したIP, portをそれぞれhost、portに指定してログイン
$ mysql --host 0.0.0.0 --port 3314 -u user -ppassword

IntelliJやSQL Clientから接続する

GUI環境から接続する際には、ターミナル上で確認したhost名ではなく 127.0.0.1 を指定して接続する必要があるよう f:id:beatdjam:20200305114734p:plain