Movatterモバイル変換


[0]ホーム

URL:


kakakakakku blog

Weekly Tech Blog: Keep on Learning!

事前にデータ投入をした MySQL Docker イメージを作る場合は /docker-entrypoint-initdb.d を活用すると便利

事前にデータ投入をした MySQL Docker イメージが必要になり,最初は「Dockerfile で頑張る感じかなぁ...」なんて考えながら調査をしていたら,公式の MySQL Docker イメージに「カスタムスクリプトを実行する機能」が用意されていることを知って,全て解決した.今までも MySQL を Docker で動かす場面はあったけど,今回の機能は知らなくて勉強になった.

CI で使うためにマイグレーション実行済の MySQL Docker イメージを用意しても良いし,新メンバーのために開発用の初期データを投入した MySQL Docker イメージを用意しても良いし,ハンズオンイベントのためにテストデータを投入した MySQL Docker イメージを用意しても良いと思う.今回の仕組みを知っておくと便利な場面は多そう.

公式のDockerfiledocker-entrypoint.sh を調べつつ,GitHub の Readme を読んでいたら,今回の機能に気付いた.

After the database is created, the entrypoint script will execute any .sh or .sql scripts found in /docker-entrypoint-initdb.d/ If you wish to execute any custom initialization scripts (e.g. for extra database or user creation), map them to this location the first time you start up the image.

github.com

github.com

動作確認

最初に動作確認をした結果を載せておこうと思う.今回まずDockerfile と投入データが入ったworld.sql.gz を用意した.データは MySQL から公開されているworld database にした.

.├── Dockerfile└── world.sql.gz

Dockerfile はシンプルで,以下のようになる.今回はサンプルとして MySQL 5.7 をベースにし,事前にworld.sql.gz を投入しておくような設定にした.ファイルをコンテナ内部の/docker-entrypoint-initdb.d にコピーしている点がポイントで,ここに置いておくだけで,自動的に実行してくれる.

FROM mysql:5.7COPY world.sql.gz /docker-entrypoint-initdb.d/world.sql.gz

実際にコンテナイメージをビルドして,コンテナを動かしてみると(オプションなどは必要に応じて),正常にデータが投入されていることを確認できた.便利!

$ docker run-eMYSQL_ALLOW_EMPTY_PASSWORD=yes-it kakakakakku/mysql-57-world-database$ dockerexec-it xxxxxxxxxxxx /bin/shmysql> SHOW DATABASES;+--------------------+| Database           |+--------------------+| information_schema || mysql              || performance_schema || sys                || world              |+--------------------+5 rowsinset (0.00 sec)mysql> USE world;mysql> SHOW TABLES;+-----------------+| Tables_in_world |+-----------------+| city            || country         || countrylanguage |+-----------------+3 rowsinset (0.00 sec)

/docker-entrypoint-initdb.d とは?

もう少し/docker-entrypoint-initdb.d の仕組みを調べてみようと思う.まずdocker-entrypoint.sh に以下のような実装があった.

for fin /docker-entrypoint-initdb.d/*;docase"$f"in        *.sh)echo"$0: running$f"; . "$f";;        *.sql)echo"$0: running$f";"${mysql[@]}"<"$f";echo;;        *.sql.gz)echo"$0: running$f"; gunzip-c"$f"|"${mysql[@]}";echo;;        *)echo"$0: ignoring$f";;esacechodone

よって,サポートされている拡張子と動作は以下となる.

  • .sh : そのまま実行する
  • .sql : mysql コマンドに流し込む
  • .sql.gz : 解凍してから mysql コマンドに流し込む

拡張子別に試してみた

さらにgrant.sqlinit.sh も追加して,全ての拡張子を試してみた.

.├── Dockerfile├── grant.sql├── init.sh└── world.sql.gz

grant.sql では,以下の通り,新規ユーザーを作成して権限を付与している.

GRANTALLPRIVILEGESON world.*TO'kakakakakku'@'localhost'IDENTIFIEDBY'kakakakakku';

init.sh では,単純に MySQL のバージョンを表示している.

#!/bin/shmysql--version

Dockerfile は,以下の通り.

FROM mysql:5.7COPY init.sh /docker-entrypoint-initdb.d/init.shCOPY world.sql.gz /docker-entrypoint-initdb.d/world.sql.gzCOPY grant.sql /docker-entrypoint-initdb.d/grant.sql

この状態でコンテナを起動すると,以下のようにログが出力されていて,正常に実行されていた.

/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/grant.sql/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.shmysql  Ver 14.14 Distrib 5.7.20, for Linux (x86_64) using  EditLine wrapper/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/world.sql.gz

新規ユーザーも作成できていた.

mysql> SELECT Host,UserFROM mysql.user;+-----------+-------------+| Host      |User        |+-----------+-------------+| %         | root        || localhost | kakakakakku || localhost | mysql.sys   || localhost | root        |+-----------+-------------+4rowsinset (0.00 sec)

実行順序に気を付ける

もし,ファイルの実行順序に依存関係がある場合,今回の仕組みではファイル名の昇順で実行されてしまうため,問題になる場合がある.その場合はDockerfile で数字などの接頭辞を付けて COPY することで,意図した順番で実行できるようになる.マイグレーションなどは,基本的にファイル名にタイムスタンプなどが入っていると思うので,大丈夫なはず.

FROM mysql:5.7COPY init.sh /docker-entrypoint-initdb.d/1_init.shCOPY world.sql.gz /docker-entrypoint-initdb.d/2_world.sql.gzCOPY grant.sql /docker-entrypoint-initdb.d/3_grant.sql

まとめ

  • 事前にデータ投入をした MySQL Docker イメージが必要な場合は/docker-entrypoint-initdb.d を使う
  • .sql だけではなく.sh.sql.gz もサポートしている
  • 実行順序に依存関係がある場合,ファイル名に気を付ける

今回,検証として world database を投入した MySQL Docker イメージを作って Docker Hub に公開してみた.MySQL のハンズオンなどに活用できそう.

github.com

関連記事

2016年に作った MySQL ハンズオン資料でも world database を使ったけど,Homebrew で MySQL をインストールして,データを投入するところから始まるので,ここを Docker イメージで置き換えてあげれば,もっと簡単に進行できそう!

github.com

プロフィール
id:kakku22id:kakku22はてなブログPro

カックです \( 'ω')/ 毎週テックブログを更新しています❗️読者登録・X フォロー・記事のシェアをしてもらえると嬉しいです〜✌

検索
お仕事の相談 💬

ソフトウェア開発全般をご支援できます😀 お仕事ウェブサイトkakakakakku.github.io からお気軽にご相談ください💪

kakakakakku | Yoshiaki Yoshida | Kakku Engineering

ブロガー応援 👏
よろしければ応援お願いします❗️コーヒー代や AWS の検証費用などに使わせていただきます☕

書籍
「AWS で実現するモダンアプリケーション入門」を出版しました❗️AWSで実現するモダンアプリケーション入門 〜サーバーレス、コンテナ、マイクロサービスで何ができるのか
Zenn Book

「LocalStack 実践入門」を執筆しました❗️

LocalStack 実践入門

LocalStack 実践入門

LocalStack 実践入門

LocalStack 実践入門

YouTube 👾

YouTube「カックマイクラ実況」を運営してます❗️チャンネル登録してもらえると嬉しいです〜カックマイクラ実況

Calendly 1on1 📅
テックブログに関する壁打ちや雑談など気軽に 1on1 をしましょう❗️

\ Calendly - カック /
カテゴリー

引用をストックしました

引用するにはまずログインしてください

引用をストックできませんでした。再度お試しください

限定公開記事のため引用できません。

読者です読者をやめる読者になる読者になる

[8]ページ先頭

©2009-2025 Movatter.jp