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) をマウントします。
ホスト側に設定ファイルを用意 (
./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起動時にマウント:
-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=ROW2. Slave側の設定
slave.cnf:
[mysqld]
server-id=2
relay-log=relay-bin
read-only=13. 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. レプリケーション開始手順
- コンテナを起動する:
docker-compose up -d - Masterでレプリケーション用ユーザーを作成する。
- Masterのステータス(File名とPosition)を確認する:
SHOW MASTER STATUS; - Slaveに入り、Masterの情報を設定して開始する:
CHANGE MASTER TO MASTER_HOST='mysql-master', MASTER_USER='repl', ...; START SLAVE;
これで、Masterに書き込んだデータが自動的にSlaveに同期されるようになります。
まとめ
DockerでMySQLを使う際は、以下の3点を必ず守ってください。
- Volumeマウントでデータを永続化する。
- Docker Composeで設定をコード管理する。
- 本番環境ではリソース制限(メモリ・CPU)を設定する。
これさえ守れば、コンテナ再起動でデータが飛ぶ悪夢を見ることはなくなります。
Docker MySQL構築フロー
データ永続化からレプリケーションまでの完全手順
⏱️ Estimated time: 30 min
- 1
Step1: ステップ1:データ永続化設定
解説:docker run時に -v mysql-data:/var/lib/mysql を指定。
重要:これを忘れるとコンテナ削除時にデータも消滅します。 - 2
Step2: ステップ2:設定ファイルの適用
解説:ホスト側にmy.cnfを作成し、-v ./my.cnf:/etc/mysql/conf.d/my.cnf でマウント。
内容:文字コード(utf8mb4)や最大接続数などを記述します。 - 3
Step3: ステップ3:Composeによる管理
解説:docker-compose.ymlを作成し、サービス定義、ボリューム、ネットワークを一元管理。
メリット:コマンド管理が不要になり、Gitで構成をバージョン管理できます。 - 4
Step4: ステップ4:レプリケーション構築(オプション)
解説:MasterとSlaveの2つのコンテナを立ち上げ、binlog連携を設定します。
効果:読み取り負荷の分散と、データ冗長化による可用性向上が実現します。
FAQ
外部からMySQLコンテナに接続できません。
Mac (M1/M2) でMySQLコンテナが重い、または落ちます。
データのバックアップはどうすればいいですか?
2 min read · 公開日: 2025年12月18日 · 更新日: 2026年1月22日
関連記事
Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践

Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践
Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド

Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド
Next.js ユニットテスト実践:Jest + React Testing Library 完全設定ガイド

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