結論
コンテナ側の /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_USER
とMYSQL_PASSWORD
を設定して一般ユーザを作成して用いることができます- ただし、この一般ユーザはデータベースを作成する権限がありません
- 環境変数の
MYSQL_DATABASE
で渡すデータベース(1つ)だけはデフォルトで作ることができます
- 以上より、「外部から接続できるような MySQL を」「比較的自由にできるユーザ(データベースを作れるなど)」を作るためには、上述のようにスクリプトで自前で補完して上げる必要があります
- 上述の方法を用いればほぼ何でもできることになりますが、基本的にはデフォルトの環境変数のみでできることで設計をするのが Docker の思想にマッチしているかと思います
参考
4年以上前の記事になりますが、以下の記事に詳しく書いていらっしゃるとおりです。
*1:MySQLだけを独立でコンテナで立てて、そこに外側からアクセスするようなケースでは接続できません