Docker Compose で MySQL 8 のコンテナを作るときに、自由にスクリプトを実行して環境を作る方法

結論

コンテナ側の /docker-entrypoint-initdb.d 配下に実行したいスクリプトを置きます。するとコンテナ作成時にそれらのスクリプトをファイル名の順番で実行してくれます。

コンテナ作成時にホスト側の適当なディレクトリにスクリプトファイルを詰め込み、そのディレクトリをコンテナ側の /docker-entrypoint-initdb.d と共有しましょう(ボリュームとして割り当てましょう)。

Docker Compose での具体例

docker-compose.yml で書くと以下のような感じになります。

version: "3"
services:
  mysql:
    image: mysql/mysql-server:8.0.22
    container_name: mysql_foobar
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --secure-file-priv=""
    environment:
      MYSQL_ROOT_PASSWORD: hogehoge
      MYSQL_USER: fugafuga
      MYSQL_PASSWORD: hogefuga
      MYSQL_DATABASE: foo_database
    ports:
      - 12345:3306
    volumes:
      - ./init_scripts:/docker-entrypoint-initdb.d
      - ./mysql_data:/var/lib/mysql

上記における - ./init_scripts:/docker-entrypoint-initdb.d のところがキモです。ホスト側の ./init_scripts 配下に適当なシェルスクリプトを置くと、コンテナ作成時にそれらがファイル名順に実行されます。

ファイル名順に実行されるので、実行したい順番を考えてファイル名に 01_ 02_ 03_ などの接頭語を付与するといいでしょう。

スクリプトの具体例

スクリプトの具体例です。例えば、以下のスクリプトでは MYSQL_USER にフル権限を与えるスクリプトです。

#!/bin/sh

echo "GRANT ALL ON *.* TO '"$MYSQL_USER"'@'%' ;" | "${mysql[@]}"
echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}"

スクリプトを含めたファイルの配置例

上記のスクリプトを例えば 01_give_full_privileges_to_mysql_user.sh と命名したとします。このとき、スクリプトを含めたファイル配置は次のようになります。

.
├── docker-compose.yml
├── init_scripts
│   └── 01_give_full_privileges_to_mysql_user.sh
└── mysql_data
    ├── (省略)

補足

  • MySQL のコンテナを作る際に MYSQL_ROOT_PASSWORD という環境変数を設定することが必要です
    • root ユーザの host は、localhost になっているため、デフォルトでは外部からの接続はできません*1
  • root の制限がきついことから、MYSQL_USERMYSQL_PASSWORD を設定して一般ユーザを作成して用いることができます
    • ただし、この一般ユーザはデータベースを作成する権限がありません
    • 環境変数の MYSQL_DATABASE で渡すデータベース(1つ)だけはデフォルトで作ることができます
  • 以上より、「外部から接続できるような MySQL を」「比較的自由にできるユーザ(データベースを作れるなど)」を作るためには、上述のようにスクリプトで自前で補完して上げる必要があります
  • 上述の方法を用いればほぼ何でもできることになりますが、基本的にはデフォルトの環境変数のみでできることで設計をするのが Docker の思想にマッチしているかと思います

参考

4年以上前の記事になりますが、以下の記事に詳しく書いていらっしゃるとおりです。

qiita.com

*1:MySQLだけを独立でコンテナで立てて、そこに外側からアクセスするようなケースでは接続できません

Powered by はてなブログ