MariaDB講座 / Docker ComposeでローカルのMariaDB実習環境を作る

Docker ComposeではMariaDBコンテナー、接続ポートと永続領域を一つの設定へまとめられます。PCへDBサービスを直接導入せず実習できますが、コンテナーを消す操作とデータボリュームを消す操作は別です。

実習の範囲と前提を確認する

Dockerはアプリケーションをコンテナーで動かし、Composeは起動構成をYAMLで定義します。ここではPCの127.0.0.1:3307へ一台のDBを公開し、既存の3306と分けます。公式手順でDocker EngineとComposeプラグイン、またはDocker Desktopを導入します。WindowsはLinuxコンテナーを使い、エンジンを開始して端末で確認します。

docker version
docker compose version

imageはmariadb:11.8という系列タグで、後のパッチへ変わり得ます。厳密な再現には承認済みパッチやdigestを記録します。この構成のYAMLとSQLの確認と、Docker上の起動・ネットワーク・永続性の実行確認は別です。後者はDocker環境で以下の結果を確かめます。

新しい作業フォルダーと秘密ファイルを作る

mariadb-appopsという新規フォルダーで端末を開き、secrets/root-password.txtとapp-password.txtへ別々の実習パスワードをUTF-8で一行ずつ保存します。空欄や説明文を入れません。次の.gitignoreも保存し、ファイルへのアクセスを制限します。

secrets/
.env

Compose secretsは選択サービスへファイルを渡しますが、元ファイルを暗号化保管庫に変えません。Dockerの操作権限と両方を保護します。無関係なComposeプロジェクトで命令を実行しないでください。

完全なcompose.yamlを保存する

次を作業フォルダーのcompose.yamlへ保存します。

name: mariadb-appops
services:
  db:
    image: mariadb:11.8
    ports:
      - "127.0.0.1:3307:3306"
    environment:
      MARIADB_ROOT_PASSWORD_FILE: /run/secrets/root_password
      MARIADB_DATABASE: appops_lab
      MARIADB_USER: app_user
      MARIADB_PASSWORD_FILE: /run/secrets/app_password
    secrets:
      - root_password
      - app_password
    volumes:
      - db_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s
secrets:
  root_password:
    file: ./secrets/root-password.txt
  app_password:
    file: ./secrets/app-password.txt
volumes:
  db_data:

ホストの3307はコンテナー内3306へ対応します。PCのクライアントは127.0.0.1:3307、同じComposeネットワークの別サービスはdb:3306です。loopbackへ限定した公開先と、サーバー内の住所を混同しません。

db_dataはデータ領域、_FILE変数はパスワードファイルです。公式イメージのDB・ユーザー・パスワード初期化は新規データ領域に適用され、初期化済みボリュームでファイルを書き換えただけでは既存ユーザーのパスワードは変わりません。healthcheck.shは接続とInnoDB準備を確認し、コンテナーがrunningだけではSQL準備完了とは限りません。

起動し、一行を保存して確認する

構文を確認して起動します。

docker compose config --quiet
docker compose up -d
docker compose ps
docker compose logs --tail=80 db

healthyになるか見ます。secretのパスや3307競合なら、データ削除より先に原因を直します。クライアントを開きます。

docker compose exec db mariadb --default-character-set=utf8mb4 -u app_user -p appops_lab

app-password.txtのパスワードを入力し、未使用表名を確認して実行します。

USE appops_lab;
CREATE TABLE docker_notes (
  note_id INT NOT NULL PRIMARY KEY,
  note_text VARCHAR(80) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO docker_notes VALUES (1, 'volume survives container replacement');
SELECT note_id, note_text FROM docker_notes;

一行が返ることを確認します。PCのクライアントを使う代替です。

mariadb --protocol=tcp --host=127.0.0.1 --port=3307 --default-character-set=utf8mb4 -u app_user -p appops_lab

ここを3306にすると別のローカルDBへつながる可能性があります。接続先の確認を使い分けます。

ボリュームを残してコンテナーを交換する

同じプロジェクトで実行します。

docker compose down
docker compose up -d

通常のdownはコンテナーとネットワークを消しますが、この名前付きボリュームは残ります。再びhealthyになったら接続し、SELECT * FROM docker_notes;で前の行があるか確認します。

down --volumesはボリュームも消し得るため再起動の代わりに使いません。実習データが不要と確認した場合だけ、削除範囲を理解して実行します。ボリュームは別バックアップの代わりではありません。

不調を初期化で隠さない

エンジンへ接続できなければ稼働とDocker context、ポート競合なら3307、認証なら初期化時の実アカウント・既存ボリュームを調べます。runningでもSQL不可ならhealthとログ、予想外のデータならプロジェクト名、フォルダー、接続ポートとマウント先を読みます。データ領域を特定してから、設定変更か新規初期化かを判断します。

関連する公式リファレンス