♻️

docker-compose.ymlのMySQL環境変数を動かしながら学ぶ

2023/03/13に公開

はじめに

DBを触る時は、DockerでMySQL環境を作ることがほとんどだが、これまでEnvironmentの内容をあまり理解せずに使っていた。そこで、環境変数にフォーカスを当ててMySQLを触ってみる。
最終的に、個人的なEnvironmentのテンプレートを見つけることを目的とする。

この記事で学びがあるかもしれない人

何らかの教材や技術記事をインプットにしてDockerを使ったことはあるが、環境変数周りはなんとなくコピペして動かしている方

環境

ファイル構成
.
└── docker-compose.yml
docker-compose.yml
version: "3"
services:
  db:
    container_name: db
    image: mysql

MYSQL_ROOT_PASSWORD

rootユーザーのパスワードを設定する。このオプションは必須

設定なしで動作確認

docker-compose.yml
version: "3"
services:
  db:
    container_name: db
    image: mysql

コンテナの起動

$ docker-compose up -d
Creating network "20230312_mysql_environment_default" with the default driver
Creating db ... done

$ docker-compose ps
Name             Command             State    Ports
---------------------------------------------------
db     docker-entrypoint.sh mysqld   Exit 1

起動すると、StateがExit 1となってしまった。
ログでエラー内容を確認する。

ログの確認

$ docker-compose logs
Attaching to db
db    | 2023-03-12 08:06:35+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.32-1.el8 started.
db    | 2023-03-12 08:06:35+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
db    | 2023-03-12 08:06:35+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.32-1.el8 started.
db    | 2023-03-12 08:06:35+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
db    |     You need to specify one of the following as an environment variable:
db    |     - MYSQL_ROOT_PASSWORD
db    |     - MYSQL_ALLOW_EMPTY_PASSWORD
db    |     - MYSQL_RANDOM_ROOT_PASSWORD

「パスワードオプション(環境変数)が指定されていないので、MYSQL_ROOT_PASSWORD
MYSQL_ALLOW_EMPTY_PASSWORDMYSQL_RANDOM_ROOT_PASSWORDを指定してください」と怒られている。

設定ありで動作確認

docker-compose.yml
version: "3"
services:
  db:
    container_name: db
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root

コンテナの起動

$ docker-compose up -d
Creating network "20230312_mysql_environment_default" with the default driver
Creating db ... done

$ docker-compose ps
Name             Command             State          Ports
----------------------------------------------------------------
db     docker-entrypoint.sh mysqld   Up      3306/tcp, 33060/tcp

無事に起動できた。念のためにログインできるかも確認。

rootでMySQLにログイン

$ docker exec -it db bash

bash-4.4# mysql -u root -p
Enter password:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.32 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

ログインできた。

MYSQL_DATABASE

イメージ起動時に作成されるデータベースの名前を指定する。

設定なしで動作確認

docker-compose.yml
version: "3"
services:
  db:
    container_name: db
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

設定ありで動作確認

docker-compose.yml
version: "3"
services:
  db:
    container_name: db
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.01 sec)

mysql>

データベースにtestが作成された。

MYSQL_USER, MYSQL_PASSWORD

新しいユーザーを作成してパスワードを設定する。
このコマンドで作成されたユーザーには、MYSQL_DATABASEで指定したDBへのスーパーユーザー権限が付与される。

設定なしで動作確認

docker-compose.yml
version: "3"
services:
  db:
    container_name: db
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test
mysql> SELECT host, user
    -> FROM mysql.user;
+-----------+------------------+
| host      | user             |
+-----------+------------------+
| %         | root             |
| localhost | mysql.infoschema |
| localhost | mysql.session    |
| localhost | mysql.sys        |
| localhost | root             |
+-----------+------------------+
5 rows in set (0.00 sec)

設定ありで動作確認

docker-compose.yml
version: "3"
services:
  db:
    container_name: db
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test
      MYSQL_USER: test
      MYSQL_PASSWORD: test
mysql> SELECT host, user
    -> FROM mysql.user;
+-----------+------------------+
| host      | user             |
+-----------+------------------+
| %         | root             |
| %         | test             |
| localhost | mysql.infoschema |
| localhost | mysql.session    |
| localhost | mysql.sys        |
| localhost | root             |
+-----------+------------------+
6 rows in set (0.00 sec)

mysql>

ユーザーにtestが追加された。

MYSQL_ALLOW_EMPTY_PASSWORD

何らかの値を設定すると、rootユーザーでのログイン時にパスが不要になる。
誰でもスーパーユーザーでアクセスできるようになるため、よく分からないうちは非推奨。

設定なしで動作確認

docker-compose.yml
version: "3"
services:
  db:
    container_name: db
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test
      MYSQL_USER: test
      MYSQL_PASSWORD: test
bash-4.4# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.32 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Enter password:と表示され、パスワードを入力しないとMySQLにログインできない。

設定ありで動作確認

docker-compose.yml
version: "3"
services:
  db:
    container_name: db
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test
      MYSQL_USER: test
      MYSQL_PASSWORD: test
      MYSQL_ALLOW_EMPTY_PASSWORD: "true"
bash-4.4# mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.32 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Enter password:が表示されず、パスワードを入力しなくともMySQLにログインできた。

MYSQL_RANDOM_ROOT_PASSWORD

設定すると、rootユーザーのパスワードをランダムな値で生成する。
生成されたパスワードはlogに出力されるので、grepで確認しよう。

設定ありで動作確認

version: "3"
services:
  db:
    container_name: db
    image: mysql
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
      MYSQL_DATABASE: test
      MYSQL_USER: test
      MYSQL_PASSWORD: test

$ docker-compose down
Stopping db ... done
Removing db ... done
Removing network 20230312_mysql_environment_default

$ docker-compose up -d
Creating network "20230312_mysql_environment_default" with the default driver
Creating db ... done

$ docker logs db 2>&1 | grep PASSWORD
2023-03-12 12:57:38+00:00 [Note] [Entrypoint]: GENERATED ROOT PASSWORD: Om2r2cwFBgHxbMrnDz/emhZkjEK0QfBm
$

ランダムな文字列でパスワード生成されていることを確認。

MYSQL_ONETIME_PASSWORD

設定を有効にすると、rootユーザーを期限切れとして設定して、初回ログイン時にパスワード変更を強制する。

MYSQL_INITDB_SKIP_TZINFO

MySQLでは、自動でタイムゾーンデータをロードしている。
MYSQL_INITDB_SKIP_TZINFOを有効にすると、タイムゾーンの自動ロードを無効にする。

個人的なEnvironmentのテンプレート

version: "3"
services:
  db:
    container_name: db
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: <パスワード>
      MYSQL_DATABASE: <データベース名>
      MYSQL_USER: <ユーザー名>
      MYSQL_PASSWORD: <パスワード>

まあ、「MySQL Docker Environment」とググったときの検索結果のほとんどはこんな感じかもしれません。
ただ、実際に色々触ってみたり公式ドキュメント読んだりすると、何でこういう記載が多いのかがよく分かりました。
公式ドキュメント、読もう。

余談

docker-compose.ymlにボリューム先を記載した状態で一度MySQLデータベースを作成した場合に、MYSQL_USERMYSQL_PASSWORDMYSQL_DATABASEの追記や修正をして再作成しても反映されなかった。

忘れるとハマりそうなので気をつけたい。

参考サイト

MySQL :: MySQL 8.0 リファレンスマニュアル :: 2.5.6.2 Docker での MySQL Server のデプロイに関するその他のトピック

mysql - Official Image | Docker Hub

Discussion