お問い合わせ
DockerでMySQLを構築する方法!Docker Composeの設定からバックアップまで解説

DockerでMySQLを構築する方法!Docker Composeの設定からバックアップまで解説

Jay-Piy wabi_motion

DockerでMySQLを構築する方法!Docker Composeの設定からバックアップまで解説

DockerでMySQLを構築する方法を解説。基本的なコンテナ起動・Docker Composeの設定・データ永続化・バックアップ・よくあるエラーの対処法まで初心者でも迷わず進められる手順をまとめました。

「DockerでMySQLを動かしたいけど何から始めればいいかわからない」という方向けに、基本的なコンテナの起動からDocker Composeを使った本格的な構成・データ永続化・バックアップまで順番に解説します。

DockerでMySQLを使うメリット

ローカルに直接MySQLをインストールすると、バージョン管理が面倒だったり、PCを変えたときにまた環境構築が必要になったりします。Dockerを使うとこれらの問題が解消されます。

  • 環境の統一:docker-compose.ymlを共有するだけでチーム全員が同じ環境を使える
  • バージョン管理が楽:MySQL 5.7と8.0を同時に起動して切り替えられる
  • 削除が簡単:コンテナを削除すれば環境がきれいに消える
  • PC本体を汚さない:ホストOSにMySQLをインストールしなくていい

MySQLコンテナを起動する

まずdocker runコマンドで素早く起動してみます。

# MySQLコンテナを起動
docker run \
  --name my-mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=rootpassword \
  -e MYSQL_DATABASE=mydb \
  -e MYSQL_USER=myuser \
  -e MYSQL_PASSWORD=mypassword \
  -d mysql:8.0

# オプションの説明
# --name               : コンテナに名前をつける
# -p 3306:3306         : ホストの3306番ポートをコンテナの3306番ポートにマッピング
# -e MYSQL_ROOT_PASSWORD: rootユーザーのパスワード(必須)
# -e MYSQL_DATABASE    : 起動時に作成するDB名
# -e MYSQL_USER        : 作成するユーザー名
# -e MYSQL_PASSWORD    : 作成するユーザーのパスワード
# -d                   : バックグラウンドで実行
# mysql:8.0            : 使用するイメージとバージョン

起動後に接続確認します。

# コンテナが起動しているか確認
docker ps

# コンテナ内のMySQLに接続
docker exec -it my-mysql mysql -u root -p
# パスワードを入力してEnter

# MySQLプロンプトが表示されれば接続成功
mysql>

# データベース一覧を確認
mysql> show databases;

# 終了
mysql> exit

ポートが使用中でコンテナが起動しない場合は-p 3307:3306のようにホスト側のポートを変えてください。

Docker ComposeでMySQLを管理する

毎回長いdocker runコマンドを打つのは面倒です。Docker Composeを使うと設定をファイルで管理できて、コマンド一つで起動・停止できます。

# docker-compose.yml
version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: my-mysql
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: mydb
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypassword
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - ./init:/docker-entrypoint-initdb.d
    command: --default-authentication-plugin=mysql_native_password
    restart: unless-stopped

volumes:
  mysql_data:
# Docker Composeの基本コマンド
# 起動
docker compose up -d

# 停止
docker compose down

# コンテナを削除してボリュームも削除(データが消えるので注意)
docker compose down -v

# ログ確認
docker compose logs mysql

# MySQLに接続
docker compose exec mysql mysql -u root -p

command: --default-authentication-plugin=mysql_native_passwordはMySQL 8.0以降で認証プラグインが変わったことによる接続エラーを回避するための設定です。古いクライアントから接続する場合に必要になることがあります。

データの永続化(ボリューム設定)

Dockerコンテナはデフォルトでは削除するとデータも消えます。ボリュームを設定することでデータを保持できます。

# ボリュームの種類

① Dockerが管理するボリューム(推奨)
volumes:
  - mysql_data:/var/lib/mysql

volumes:
  mysql_data:

# Dockerが/var/lib/docker/volumes/に保存する
# パーミッションの問題が起きにくい

② ホストのディレクトリをマウント
volumes:
  - ./mysql-data:/var/lib/mysql

# ホストのディレクトリに保存する
# パーミッションエラーが発生することがある
# 対処:chmod 777 ./mysql-data(本番環境では厳密に設定すること)
# ボリュームの確認
docker volume ls

# ボリュームの詳細
docker volume inspect mysql_data

ボリュームを使っていてもコンテナを削除するとマウントは外れますが、データは残ります。次回コンテナを起動するときに同じボリュームをマウントすればデータが復元されます。

初期化SQLを自動実行する

コンテナ起動時にテーブル作成やデータ投入を自動で実行できます。

# ディレクトリ構成
.
├── docker-compose.yml
└── init/
    ├── 01_create_tables.sql
    └── 02_insert_data.sql
# 01_create_tables.sql
CREATE TABLE IF NOT EXISTS users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(100) UNIQUE NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

# 02_insert_data.sql
INSERT INTO users (name, email) VALUES
  ('田中太郎', 'tanaka@example.com'),
  ('佐藤花子', 'sato@example.com');
# docker-compose.ymlのvolumes設定
volumes:
  - ./init:/docker-entrypoint-initdb.d

/docker-entrypoint-initdb.dに置いたSQLファイルはコンテナの初回起動時に自動実行されます。ファイル名の順番で実行されるので番号プレフィックスをつけると管理しやすいです。

WebアプリとMySQLをDocker Composeで連携する

Node.jsアプリとMySQLを連携させる例です。

# docker-compose.yml(Node.js + MySQL)
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      DB_HOST: mysql      # サービス名で接続できる
      DB_USER: myuser
      DB_PASSWORD: mypassword
      DB_NAME: mydb
    depends_on:
      mysql:
        condition: service_healthy

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: mydb
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypassword
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  mysql_data:

depends_onだけではMySQLの起動完了を待てません。healthcheckcondition: service_healthyを組み合わせることで、MySQLが準備できてからアプリが起動するようになります。

バックアップとリストア

バックアップ

# mysqldumpでバックアップ
docker exec my-mysql mysqldump \
  -u root -prootpassword \
  --databases mydb \
  > backup_$(date +%Y%m%d).sql

# 全データベースをバックアップ
docker exec my-mysql mysqldump \
  -u root -prootpassword \
  --all-databases \
  > backup_all_$(date +%Y%m%d).sql

リストア

# バックアップファイルからリストア
docker exec -i my-mysql mysql \
  -u root -prootpassword \
  mydb < backup_20240101.sql

パスワードを-pの直後に書く方法はセキュリティ上好ましくないです。本番環境では環境変数や設定ファイルで管理することを検討してください。

# より安全なバックアップ方法(パスワードをプロンプトで入力)
docker exec -it my-mysql mysqldump \
  -u root -p \
  --databases mydb \
  > backup.sql

パフォーマンスチューニング

MySQLの主要なパフォーマンス設定をカスタマイズする方法です。

# my.cnf(MySQLの設定ファイル)
[mysqld]
# バッファプールサイズ(メモリの50〜80%が目安)
innodb_buffer_pool_size = 512M

# 接続数の上限
max_connections = 100

# クエリキャッシュ(MySQL 8.0では削除済み)
# MySQL 5.7以前の場合のみ有効
# query_cache_size = 64M

# 一時テーブルのメモリサイズ
tmp_table_size = 64M
max_heap_table_size = 64M

# スロークエリログ(1秒以上かかったクエリを記録)
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
# docker-compose.ymlで設定ファイルをマウント
services:
  mysql:
    image: mysql:8.0
    volumes:
      - mysql_data:/var/lib/mysql
      - ./my.cnf:/etc/mysql/conf.d/my.cnf:ro
    deploy:
      resources:
        limits:
          memory: 1G    # コンテナのメモリ上限
          cpus: '1.0'   # CPU上限

よくあるエラーと対処法

# エラー①:ポートが使用中
Error: Bind for 0.0.0.0:3306 failed: port is already allocated
対処:-p 3307:3306 でホスト側のポートを変える

# エラー②:接続できない(コンテナ起動直後)
ERROR 2002 (HY000): Can't connect to local MySQL server
対処:MySQLの起動に数秒かかるので少し待ってから接続する
healthcheckを設定してdepends_onと組み合わせる

# エラー③:認証エラー
ERROR 1045 (28000): Access denied for user 'root'@'localhost'
対処:パスワードを確認
コンテナを削除してボリュームも削除してから再作成
docker compose down -v && docker compose up -d

# エラー④:ボリュームのパーミッションエラー
mysqld: Can't create/write to file '/var/lib/mysql/'
対処:Dockerが管理するボリュームを使う
ホストディレクトリをマウントする場合はchmod 777を確認

# エラー⑤:YAMLのインデントミス
yaml: line XX: mapping values are not allowed in this context
対処:スペース2つでインデントを統一する
タブ文字を使わない

まとめ

DockerでMySQLを構築する基本の流れをまとめます。

  • まずdocker runでMySQLを起動して接続確認する
  • 設定が固まったらdocker-compose.ymlに移行する
  • ボリュームを設定してデータを永続化する
  • 初期化SQLで起動時のテーブル作成・データ投入を自動化する
  • 定期的にmysqldumpでバックアップを取る

まずはdocker compose up -dでMySQLを起動してみるところから始めてください。

最後までお読みいただき、誠にありがとうございました。

ITエンジニアとして働きながら、AI・映像制作・AWSについて実体験をもとに発信しています。少しでも参考になれば嬉しいです。

他の記事もぜひ読んでみてください。