1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Dockerインスタンス起動にDB初期化を自動化する(PHP/nginx/MySQL)

1
Last updated at Posted at 2026-06-12

はじめに

前回のブログ内容に続いています。
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-cache

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

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?