はじめに
前回のブログ内容に続いています。
devcontainerでPHPフルスタックアプリケーション開発環境を作成、その際Dockerコンテナ起動に合わせてMySQLも初期化できるように設定しました。失敗についても書きます!
結論
/docker-entrypoint-initdb.dを使うとコンテナ起動時にデータベース初期化を行うことができる。
達成したかったこと
devcontainer起動時にデータベースの初期化を自動化したいと思いました。
ディレクトリは以下の通りです。
my-php-app/
│
├── .devcontainer/
│ ├── devcontainer.json # 開発環境の設定
│ └── docker-compose.yml # php, nginx, dbと各コンテナを設定
│
├── mysql/
│ ├── initdb/
│ │ ├── 01-create-user.sh # ユーザー作成スクリプト
│ │ └── 02-schema.sql # テーブル作成スクリプト
│ ├── entrypoint.sh
│ └── Dockerfile
├── nginx/
│ ├── default.conf
│ └── Dockerfile
│
├── php_code/
│ ├── index.php
│ └── Dockerfile
│
└── README.md
設定は以下のとおりです。(完成形)
docker-compose.yml
version: "3.9"
services:
nginx:
build: ../nginx/
ports:
- 80:80
volumes:
- ../:/var/www/html/
php:
build: ../php/
volumes:
- ../:/var/www/html/
db:
image: ../mysql/
volumes:
- mysql-data:/var/lib/mysql
- ../mysql/initdb:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: mariadb
MYSQL_DATABASE: memopad
volumes:
mysql-data:
Dockerfile
FROM mariadb
# エントリーポイントスクリプトをコピー
COPY --chmod=744 ./entrypoint.sh /usr/local/bin/
# エントリーポイントを設定
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["mariadbd"]
entrypoint.sh
#!/bin/bash
# 権限を設定
chmod +x /docker-entrypoint-initdb.d/01-create-user.sh
# MariaDBのエントリーポイントを実行
exec docker-entrypoint.sh "$@"
devcontainerを起動した場合のおおまかな動きは次の通りです。
-
/mysql配下のDockerfileがビルド開始する (devcontainer) - ホストマシンの
entrypoint.shがパーミッションの変更と同時に/usr/local/bin配下にコピーされる(Dockerfile) -
ENTRYPOINT /user/local/bin/entrypoint.shにて当該ファイルが dbコンテナのエントリーポイントとしてコンテナ起動時に実行される(Dockerfile) -
/docker-entrypoint-initdb.d/01-create-user.shのパーミッションを変更し、MySQLのエントリーポイントを実行する(entrypoint.sh) - 上記の結果、データベースが初期化される
/docker-entrypoint-initdb.d/はその配下にスクリプトを置くとデータベースの初期化を実行してくれる設定です。
If there are any `.sh` or `.sql` scripts you want to run on the database immediately after it has been created,
you can put them into a host directory and then mount the directory at `/docker-entrypoint-initdb.d/` inside the container.
2.5.6.2 More Topics on Deploying MySQL Server with Docker
How to Initialize MySQL in Docker with SQL Scripts
課題
.sqlスクリプトはMySQLが読み込むのでファイルのパーミッションはデフォルトのままで良いのですが、.shのスクリプトはDockerが実行するためパーミッションを変更しなくてはなりません。
ホストマシンでファイルの権限を変更すればその権限をそのままDockerコンテナにも反映させられるのですが、開発手順をできる限り自動化することが理想なのでパーミッションの変更を設定に追加しました。
達成に至るまで
失敗1 - パーミッションを変更するタイミング
Dockerfile内でファイルの権限を変更したところ、build時はファイルのパーミッションを変更できているのですが、devcontainerを起動すると変更されていない事象に遭遇しました。
これは、docker-compose.yml で docker-entrypoint-initdb.dをホストマシンにマウントするので、ホストマシンのファイルが反映されるためです。
余談ですが、ビルドコンテキストの確認は次のコマンドが便利です。Dockerfile に RUN ls -la など追加するとファイルの状況を確認できます。
docker-compose build --progress=plain --no-cache
Dockerfileをbuild時にログを出して楽にデバッグしよう!
コンテナ起動時のエントリーポイントにて実行することで解決しました。
失敗2 - /docker-entrypoint-initdb.d配下に置くべきファイルとは
entrypoint.sh を /mysql/initdb 配下に置いていたところ、コンテナ起動時に次のエラーメッセージに遭遇しました。
2026-06-11 16:04:02+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/01-create-user.sh
2026-06-11 16:04:02+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/02-schema.sql
2026-06-11 16:04:02+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/entrypoint.sh
/usr/local/bin/docker-entrypoint.sh: /docker-entrypoint-initdb.d/entrypoint.sh: /bin/bash: bad
interpreter: Permission denied
ホストマシンの/mysql/initdb/が/docker-entrypoint-initdb.d/にマウントされるため、コンテナ起動時のデータベース初期化として/mysql/initdb/配下のsql, shファイルが実行されるためです。
entrypoint.shはデータベース初期化には直接関連しないため、ホストマシン上でファイルをルート配下に移動することで解決しました。
まとめ
/docker-entrypoint-initdb.d/はその配下にスクリプトを置くとデータベースの初期化を実行してくれるのでとても便利です!
もしお気づきのことがあればご指摘いただけると幸いです。
参考リンク