msano / PHP/Nginx/MySQL - Dockerインスタンス起動時のDB初期化を自動化する

Created Thu, 11 Jun 2026 18:57:26 +0000 Modified Thu, 25 Jun 2026 19:39:16 +0000
1921 Words

はじめに

前回のブログ内容に続いています。 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を起動した場合のおおまかな動きは次の通りです。

  1. /mysql 配下の Dockerfileがビルド開始する (devcontainer)
  2. ホストマシンの entrypoint.shがパーミッションの変更と同時に /usr/local/bin配下にコピーされる(Dockerfile)
  3. ENTRYPOINT /user/local/bin/entrypoint.shにて当該ファイルが dbコンテナのエントリーポイントとしてコンテナ起動時に実行される(Dockerfile)
  4. /docker-entrypoint-initdb.d/01-create-user.shのパーミッションを変更し、MySQLのエントリーポイントを実行する(entrypoint.sh)
  5. 上記の結果、データベースが初期化される

/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コンテナにも反映させられるのですが、開発手順をできる限り自動化することが理想なのでパーミッションの変更を設定に追加しました。

Linuxの権限確認と変更(chmod)(超初心者向け)

達成に至るまで

失敗1 - パーミッションを変更するタイミング

Dockerfile内でファイルの権限を変更したところ、build時はファイルのパーミッションを変更できているのですが、devcontainerを起動すると変更されていませんでした。 これは、docker-compose.ymldocker-entrypoint-initdb.dをホストマシンにマウントするので、ホストマシンのファイルが反映されるためです。

余談ですが、ビルドコンテキストの確認は次のコマンドが便利です。Dockerfile に RUN ls -la など追加するとファイルの状況を確認できます。

docker-compose build --progress=plain --no-cash

Dockerfileをbuild時にログを出して楽にデバッグしよう!

私のケースだとコンテナ起動時のエントリーポイントで実行するのがベストです。

dockerコンテナ起動時に実行する.shファイルの権限

失敗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/はその配下にスクリプトを置くとデータベースの初期化を実行してくれるのでとても便利です!。

参考リンク

2.5.6.2 More Topics on Deploying MySQL Server with Docker

How to Initialize MySQL in Docker with SQL Scripts