LoginSignup
13
11

More than 1 year has passed since last update.

Dockerコンテナ起動した時にDBのテーブルが作成される仕組みの確認

Last updated at Posted at 2022-02-26

研修でのアプリ作成の開発環境に、これまでに用意いただいて使用していた、あり合わせの Dockerfile 、 docker-compose.yml を使用していました。

コードレビューしていただいた時に「ところで、Dockerコンテナを作成・起動した時に、MySQLのデータベースにテーブルが作成されるのはなんで?」と確認の質問をいただき、さっぱり答えられなかったので、 答えられるよう理解するためのアウトプットです。

1. 理解したいこと

  • 下記Docker関連のファイルの中で、DBのテーブル(下記の docker/mysql/initdb.d/01_products.sql )を自動作成してくれている仕組みを理解したい。

docker-compose.yml

version: "3.6"
services:
  web:
    build:
      context: .
      dockerfile: ./docker/nginx/Dockerfile
    depends_on:
      - app
    ports:
      - ${WEB_PORT:-80}:80
    volumes:
      - ./doc_root/public:/var/www/sample-app/public

  app:
    build:
      context: .
      dockerfile: ./docker/php/Dockerfile
    environment:
      MYSQL_DATABASE: ${DB_NAME:-sample_app}
      MYSQL_USER: ${DB_USER:-db_user}
      MYSQL_PASSWORD: ${DB_PASS:-secret}
    depends_on:
      - db
    links:
      - db:mysql
    volumes:
      - ./docker/php/php.ini:/usr/local/etc/php/php.ini
      - ./doc_root:/var/www/sample-app

  db:
    build:
      context: .
      dockerfile: ./docker/mysql/Dockerfile
    environment:
      MYSQL_DATABASE: ${DB_NAME:-sample_app}
      MYSQL_USER: ${DB_USER:-db_user}
      MYSQL_PASSWORD: ${DB_PASS:-secret}
      MYSQL_ROOT_PASSWORD: ${DB_PASS:-secret}
    ports:
      - ${DB_PORT:-3306}:3306
    volumes:
      - db-data:/var/lib/mysql
volumes:
  db-data:
    driver: local

docker/mysql/Dockerfile

FROM mysql:5.6

# timezone environment
ENV TZ=Asia/Tokyo

COPY ./docker/mysql/my.cnf /etc/mysql/conf.d/my.cnf
COPY ./docker/mysql/initdb.d /docker-entrypoint-initdb.d

CMD [ "mysqld", "--character-set-server=utf8", "--collation-server=utf8_unicode_ci" ]

docker/mysql/initdb.d/01_products.sql

SET CHARACTER_SET_CLIENT = utf8;
SET CHARACTER_SET_CONNECTION = utf8;

CREATE TABLE products (
    id                    INTEGER AUTO_INCREMENT PRIMARY KEY,
    price                 INTEGER NOT NULL,
    image                 VARCHAR(256),
    delete_flag           BOOLEAN NOT NULL DEFAULT FALSE,
    created_at            DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at            DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

docker/mysql/my.cnf

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

[client]
default-character-set=utf8mb4

2. わからないこと

  • 上記Docker関連のファイルの中で、テーブルを自動作成してくれている仕組みがわからない。

docker/mysql/Dockerfile のテーブル作成に関連すると思う箇所

COPY ./docker/mysql/initdb.d /docker-entrypoint-initdb.d

3. 調べたこと

Initializing a fresh instance

When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh.sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.

(以下、DeepL翻訳)
新しいインスタンスの初期化

コンテナが初めて起動されると、指定された名前の新しいデータベースが作成され、提供された設定変数で初期化されます。さらに、/docker-entrypoint-initdb.d にある拡張子 .sh, .sql, .sql.gz のファイルがアルファベット順で実行されます。このディレクトリにSQLダンプをマウントすることで、簡単にmysqlサービスにデータを取り込むことができ、カスタムイメージにデータを提供することができます。SQLファイルはデフォルトでMYSQL_DATABASE変数で指定されたデータベースにインポートされます。

上記のとおり、/docker-entrypoint-initdb.d にある拡張子 .sql を実行するようになっており、

COPY ./docker/mysql/initdb.d /docker-entrypoint-initdb.d

でコピーされたファイルを、実行してくれていることがわかりました!

その他、調べたこと

mysqld

CMD [ "mysqld", "--character-set-server=utf8", "--collation-server=utf8_unicode_ci" ]

mysqld とは

mysqld は、MySQL サーバーとも呼ばれ、MySQL インストールでのほとんどの作業を実行するメインプログラムです。MySQL サーバーは、データベースおよびテーブルを含む MySQL データディレクトリへのアクセスを管理します。データディレクトリは、ログファイルおよびステータスファイルなど、その他の情報のデフォルトの場所でもあります。

Docker コンテナ(dbコンテナ)起動時のログの確認

  • ログ(抜粋)
2022-02-17 10:08:54+09:00 [Note] [Entrypoint]: Database files initialized
2022-02-17 10:08:54+09:00 [Note] [Entrypoint]: Starting temporary server
2022-02-17 10:08:54+09:00 [Note] [Entrypoint]: Waiting for server startup
2022-02-17 10:08:55+09:00 [Note] [Entrypoint]: Temporary server started.
2022-02-17 10:08:59+09:00 [Note] [Entrypoint]: Creating database sample_app
2022-02-17 10:08:59+09:00 [Note] [Entrypoint]: Creating user db_user
2022-02-17 10:08:59+09:00 [Note] [Entrypoint]: Giving user db_user access to schema sample_app

2022-02-17 10:08:59+09:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/01_products.sql

2022-02-17 10:08:59+09:00 [Note] [Entrypoint]: Stopping temporary server
2022-02-17 10:09:01+09:00 [Note] [Entrypoint]: Temporary server stopped

2022-02-17 10:09:01+09:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
13
11
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
13
11