rukurxの日記

自分の日々の作業や調べたことのメモ

DockerでローカルのMySQL環境を構築する

Macのローカル環境にDockerでMySQL立てた時のメモ。

ディレクトリ構成は以下を想定。

docker-compose.yml
docker
  - db
    - conf.d
      - my.cnf
    - data
    - initdb.d
      - 001_init.sql

まずはdocker-compose.ymlを用意。 Volumesでローカルのディレクトリ/ファイルをコンテナにマウントする。 /docker/db/data でデータを永続化できる データ消す場合はこのディレクトリ以下を削除する必要がある。

version: "3"

services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: mydb
      MYSQL_USER: mydb
      MYSQL_PASSWORD: mydb
      TZ: "Asia/Tokyo"
    volumes:
      - ./docker/db/conf.d:/etc/mysql/conf.d
      - ./docker/db/initdb.d:/docker-entrypoint-initdb.d
      - ./docker/db/data:/var/lib/mysql
    ports:
      - "3306:3306"

続いてmy.cnfを用意。

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
sql_mode = STRICT_TRANS_TABLES
skip-character-set-client-handshake
collation-server = utf8mb4_general_ci
init-connect = SET NAMES utf8mb4
bind-address = 0.0.0.0

これだけあればとりあえずMySQLのコンテナを立ち上げられるので試す。

$ docker-compose up db

rootユーザでログインする。

$ mysql -uroot -p -h 127.0.0.1
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.24 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, 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 |
| mydb               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.02 sec)

docker-compose.ymlで指定したユーザmydbでログインする。

$ mysql -umydb -p -h 127.0.0.1
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.24 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, 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 |
| mydb               |
+--------------------+
2 rows in set (0.01 sec)

起動時に初期化したい場合は docker/db/initdb.d/ にシェルやSQLファイルを置くと実行される。 試しに初期化時に2つ目のテスト用のテーブルを作成する。 001-create.sql

CREATE DATABASE IF NOT EXISTS mydb;
GRANT ALL ON *.* to 'mydb'@'%';

シェルにしたい場合。 001-create.sh

#!/bin/sh

echo "CREATE DATABASE IF NOT EXISTS test_mydb;"
echo "GRANT ALL ON *.* to 'mydb'@'%';"

環境変数を使って docker-compose.yml を汎用的にする

.env

MYSQL_PORT=3306
MYSQL_DATABASE=mydb
MYSQL_USER=mydb
MYSQL_PASSWORD=mydb
MYSQL_TEST_DATABASE=test_mydb

環境変数使った docker-compose.yml

version: '3'

services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_TEST_DATABASE: ${MYSQL_TEST_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      TZ: "Asia/Tokyo"
    volumes:
      - ./docker/db/conf.d:/etc/mysql/conf.d
      - ./docker/db/initdb.d:/docker-entrypoint-initdb.d
      - ./docker/db/data:/var/lib/mysql
    ports:
      - "${MYSQL_PORT:-3306}:3306"

初期化用のシェルも環境変数使う場合。

#!/bin/sh

# Django TEST DB
if [ "$MYSQL_TEST_DATABASE" ]; then
    echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_TEST_DATABASE\` ;" | "${mysql[@]}"
    echo "GRANT ALL ON \`$MYSQL_TEST_DATABASE\`.* TO '$MYSQL_USER'@'%' ;" | "${mysql[@]}"
    echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}"
fi

プログラム側からMySQLに接続するように以下の環境変数も追加しておくと便利。 .env

MYSQL_HOST=127.0.0.1
DATABASE_URL=mysql://mydb:mydb@127.0.0.1:3306/mydb