Docker の MariaDB / MySQL イメージを使うときの tips
Docker で MariaDB / MySQL イメージを使うときのプチ tips をいくつかまとめました。
対象イメージは mariadb:10.5
と mysql:5.7
ですが、他のバージョンのものでも使えることが多いと思います。
目次
日本語サポートを改善する
character set はデフォルトでは utf8
になっています。
これを utf8mb4
に変更したい場合は、実行コマンドを上書きして --character-set-server
オプションで指定します。
これをやる場合は通常 collation も変更したくなるので、 --collation-server
オプションであわせてセットします。
Docker Compose では次のようにします。
docker-compose.yml
:
version: "3"
services:
db:
image: mariadb:10.5
command:
- mysqld
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
ちなみに、 MariaDB / MySQL の character set の utf8
と utf8mb4
の違いを知りたい方のためにかんたんに説明すると、どちらも UTF8 のための character set である点は共通していますが、次のような違いがあります:
utf8
はutf8mb3
のエイリアスで、 3 バイトまでの文字にのみ対応しているutf8mb4
はutf8mb3
がサポートする文字に加えて 4 バイトの文字にも対応している
utf8
では漢字や絵文字が十分にサポートされていません。
utf8mb4
は utf8
のスーパーセットになっているので、特殊な事情が無いかぎり通常は utf8mb4
の方を使うべきです。
参考:
- encoding - What is the difference between utf8mb4 and utf8 charsets in MySQL? - Stack Overflow
- MySQL :: MySQL Reference Manual :: 10.9 Unicode Support
- MySQL :: MySQL Reference Manual :: 10.9.1 The utf8mb4 Character Set (4-Byte UTF-8 Unicode Encoding)
データベースをダンプする
volume に保存してあるデータベースをダンプするには次のようにします。
docker exec container_id sh -c 'mysqldump --user="$MYSQL_USER" --password="$MYSQL_PASSWORD" "$MYSQL_DATABASE"' > /tmp/dumped.sql
container_id
にはコンテナの ID を渡します。
出力先の /tmp/dumped.sql
にはホスト側のパスを指定します。
初回は末尾のリダイレクト > /tmp/dumped.sql
を付けずに標準出力で確認するとよいと思います。
Docker Compose の場合は次のようにします。
docker-compose up -d
docker-compose exec service_name sh -c 'mysqldump --user="$MYSQL_USER" --password="$MYSQL_PASSWORD" "$MYSQL_DATABASE"' > /tmp/dumped.sql
docker-compose exec
は対象のコンテナが起動した後に実行します。
service_name
にはそのサービスの名前を入れます。
公式の説明では環境変数 MYSQL_ROOT_PASSWORD
が使える想定で root ユーザーを使用していますが、 root のパスワードを MYSQL_RANDOM_ROOT_PASSWORD
でセットした場合には MYSQL_ROOT_PASSWORD
は使えないため、このように MYSQL_USER
と MYSQL_PASSWORD
を使う必要があると思います。
ちなみに、ブラウザ UI を使いたい場合は Adminer あたりを使うとよいです。 Adminer は MariaDB / MySQL 以外のデータベースもいくつかサポートしています。
docker-compose.yml
:
version: "3"
services:
adminer:
image: adminer
restart: always
ports:
- 8080:8080
参考:
データベースをリストアする
一度ダンプしたデータベースを流し込むには次のようにします。
docker exec -i container_id sh -c 'mysql --user="$MYSQL_USER" --password="$MYSQL_PASSWORD" "$MYSQL_DATABASE"' < /tmp/dumped.sql
container_id
にはコンテナの ID を渡します。
/tmp/dumped.sql
にはホスト側に存在する流し込みたい SQL ファイルを指定します。
Docker Compose の場合は次のようにします。
docker-compose up -d
docker-compose exec -T service_name sh -c 'mysql --user="$MYSQL_USER" --password="$MYSQL_PASSWORD" "$MYSQL_DATABASE"' < /tmp/dumped.sql
docker-compose exec
は対象のコンテナが起動した後に実行します。
service_name
にはそのサービスの名前を入れます。
タイムゾーンをセットする
タイムゾーンをセットしたい場合は、環境変数 TZ
をセットすれば OK です。
docker-compose.yml
:
version: "3"
services:
db:
image: mariadb:10.5
environment:
TZ: "Asia/Tokyo"
タイムゾーンはログ出力の日時等に影響します。 ちなみにログのフォーマットは固定なので変更できません。
起動を待つ
MariaDB / MySQL コンテナを利用する他のコンテナで MariaDB / MySQL の起動を待ちたい場合は、 wait-for-it.sh
等の定番のスクリプトを使用するのがかんたんです。
docker-compose.yml
version: "3"
services:
db:
image: mariadb:10.5
app:
build: .
depends_on:
- "db"
command:
- ./wait-for-it.sh
- db:3306
- --
- python
- app.py
参考:
これは Docker 公式ドキュメントでも紹介されている方法です。
同種のスクリプトやコマンドがたくさん提供されているので、必ずしも wait-for-it.sh
を使う必要はありません。
用途と好みにあったものを使うとよいと思います。
もしこのあたりのツールを使いたくなければ、自前のシェルスクリプトで待つ形でも OK です。
以上です。