言語を切り替える
テーマを切り替える

DockerでMySQL構築:データ永続化から主従レプリケーションまでの完全ガイド

深夜3時、ターミナルのエラーメッセージを前に、冷や汗が止まりませんでした。「半月分のテストデータが消えた」。理由は単純、午後にMySQLコンテナを再起動したからです。

当時の私は「DockerでMySQL? docker run でパスワード指定すれば終わりでしょ?」と軽く考えていました。しかし、コンテナは「使い捨て」が前提です。コンテナを消せば、中のデータも一緒に消える——そんな当たり前のことに、痛い目を見るまで気づかなかったのです。

この記事では、私と同じ失敗をしないために、DockerでMySQLを運用するための正しい手順を解説します。基本的なデータの永続化から、カスタム設定ファイルの読み込み、そして本番環境を意識した「主従レプリケーション(Master-Slave)」の構築まで、全ての工程を網羅しました。

基礎:単体MySQLの正しい起動方法

なぜ docker run だけではダメなのか

よくある「とりあえず動かす」コマンドはこれです:
docker run --name mysql-test -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0

これで確かにMySQLは動きます。しかし、このコンテナ (mysql-test) を削除すると、中に保存したデータも完全に消滅します。

データ永続化(Volumeマウント)

データを守るには、コンテナ内のデータ保存領域(/var/lib/mysql)を、ホスト側のディレクトリに「紐付け(マウント)」する必要があります。

docker run --name mysql-persistent \
  -e MYSQL_ROOT_PASSWORD=rootpwd123 \
  -p 3306:3306 \
  -v mysql-data:/var/lib/mysql \  # これが重要!
  -d mysql:8.0

-v mysql-data:/var/lib/mysql の意味は、「ホスト側に mysql-data という名前の保管場所(Volume)を作り、それをコンテナ内の /var/lib/mysql と同期させる」ということです。これならコンテナを消しても、Volume mysql-data は残ります。

カスタム設定ファイル(my.cnf)を使う

文字コードを utf8mb4 にしたい、最大接続数を増やしたい……そんな時は設定ファイル (my.cnf) をマウントします。

  1. ホスト側に設定ファイルを用意 (./conf/my.cnf):

    [mysqld]
    character-set-server=utf8mb4
    collation-server=utf8mb4_unicode_ci
    max_connections=1000
    default_authentication_plugin=mysql_native_password
    
    [client]
    default-character-set=utf8mb4
  2. 起動時にマウント:

    -v $(pwd)/conf:/etc/mysql/conf.d

    ※ MySQL公式イメージは /etc/mysql/conf.d 内のファイルを読み込みます。

実践:Docker Composeで管理する

毎回長い docker run コマンドを打つのは大変です。docker-compose.yml でコード化しましょう。

構成例

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: mysql-standalone
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: rootpwd123
      MYSQL_DATABASE: myapp
      MYSQL_USER: appuser
      MYSQL_PASSWORD: apppwd123
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
      - ./conf/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./logs:/var/log/mysql
    networks:
      - mysql-network
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-prootpwd123"]
      interval: 10s
      timeout: 5s
      retries: 3

volumes:
  mysql-data:

networks:
  mysql-network:
    driver: bridge

これで docker-compose up -d コマンド一発で起動できます。

上級:主従レプリケーション(Master-Slave)構築

負荷分散やバックアップのために、Master(書き込み用)とSlave(読み取り用)の2台構成を作ってみましょう。

1. Master側の設定

master.cnf:

[mysqld]
server-id=1
log-bin=mysql-bin
binlog-format=ROW

2. Slave側の設定

slave.cnf:

[mysqld]
server-id=2
relay-log=relay-bin
read-only=1

3. Docker Compose構成

version: '3.8'

services:
  mysql-master:
    image: mysql:8.0
    container_name: mysql-master
    environment:
      MYSQL_ROOT_PASSWORD: rootpwd123
    volumes:
      - ./conf/master.cnf:/etc/mysql/conf.d/master.cnf
      - master-data:/var/lib/mysql
    networks:
      - replication-net

  mysql-slave:
    image: mysql:8.0
    container_name: mysql-slave
    environment:
      MYSQL_ROOT_PASSWORD: rootpwd123
    ports:
      - "3307:3306"  # ホストからはポート3307でアクセス
    volumes:
      - ./conf/slave.cnf:/etc/mysql/conf.d/slave.cnf
      - slave-data:/var/lib/mysql
    networks:
      - replication-net
    depends_on:
      - mysql-master

volumes:
  master-data:
  slave-data:

networks:
  replication-net:

4. レプリケーション開始手順

  1. コンテナを起動する:docker-compose up -d
  2. Masterでレプリケーション用ユーザーを作成する。
  3. Masterのステータス(File名とPosition)を確認する:SHOW MASTER STATUS;
  4. Slaveに入り、Masterの情報を設定して開始する:
    CHANGE MASTER TO MASTER_HOST='mysql-master', MASTER_USER='repl', ...;
    START SLAVE;

これで、Masterに書き込んだデータが自動的にSlaveに同期されるようになります。

まとめ

DockerでMySQLを使う際は、以下の3点を必ず守ってください。

  1. Volumeマウントでデータを永続化する。
  2. Docker Composeで設定をコード管理する。
  3. 本番環境ではリソース制限(メモリ・CPU)を設定する。

これさえ守れば、コンテナ再起動でデータが飛ぶ悪夢を見ることはなくなります。

Docker MySQL構築フロー

データ永続化からレプリケーションまでの完全手順

⏱️ Estimated time: 30 min

  1. 1

    Step1: ステップ1:データ永続化設定

    解説:docker run時に -v mysql-data:/var/lib/mysql を指定。
    重要:これを忘れるとコンテナ削除時にデータも消滅します。
  2. 2

    Step2: ステップ2:設定ファイルの適用

    解説:ホスト側にmy.cnfを作成し、-v ./my.cnf:/etc/mysql/conf.d/my.cnf でマウント。
    内容:文字コード(utf8mb4)や最大接続数などを記述します。
  3. 3

    Step3: ステップ3:Composeによる管理

    解説:docker-compose.ymlを作成し、サービス定義、ボリューム、ネットワークを一元管理。
    メリット:コマンド管理が不要になり、Gitで構成をバージョン管理できます。
  4. 4

    Step4: ステップ4:レプリケーション構築(オプション)

    解説:MasterとSlaveの2つのコンテナを立ち上げ、binlog連携を設定します。
    効果:読み取り負荷の分散と、データ冗長化による可用性向上が実現します。

FAQ

外部からMySQLコンテナに接続できません。
2つの原因が考えられます。1つはポートマッピング忘れ(-p 3306:3306)。もう1つはMySQLユーザーの権限設定です。デフォルトのrootユーザーはlocalhostのみ許可されている場合があるので、`docker exec`で入り、`UPDATE mysql.user SET host='%' WHERE user='root';` 等で権限を変更する必要があります(開発環境のみ)。
Mac (M1/M2) でMySQLコンテナが重い、または落ちます。
MySQLの純正イメージはamd64向けに最適化されており、arm64アーキテクチャ(Apple Silicon)ではエミュレーションにより動作が不安定になることがあります。`platform: linux/amd64` を指定するか、arm64にネイティブ対応している `mariadb` イメージの使用を検討してください。
データのバックアップはどうすればいいですか?
最も確実なのは `mysqldump` コマンドです。`docker exec mysql-container mysqldump -u root -p dbname > backup.sql` のように、ホスト側からコンテナ内のコマンドを実行して出力します。または、Volumeディレクトリごとバックアップする方法もあります。

2 min read · 公開日: 2025年12月18日 · 更新日: 2026年1月22日

コメント

GitHubアカウントでログインしてコメントできます

関連記事