TS-Tech
DB/SQL

Docker で MySQL / PostgreSQL の SQL 環境を構築する

8
  • 環境構築

Docker で MySQL / PostgreSQL の SQL 環境を構築する

手元に MySQL や PostgreSQL を直接入れると、OS ごとに手順が違い、ポートがぶつかったりバージョンが揃わなかったりしやすいです。ここではリポジトリ DB_SQLMySQL_setupPostgreSQL_setup を使い、Docker Compose で練習用の DB を立ち上げます。所要はだいたい 20〜40 分(片方だけなら 15 分前後)。やることは起動・接続確認と、init / ボリュームの挙動理解までで、SQL の文法やインデックスの話はしません。

Docker Desktop、または Docker Engine + Compose があれば十分です。どちらも公式イメージをそのまま使うので、ビルドは不要で docker compose up -d から始められます。

詳細手順の原本: MySQL_setup/README.md · PostgreSQL_setup/README.md


目次

  1. この記事でできること
  2. 前提条件
  3. 全体像:2 つのセットアップの共通設計
  4. MySQL 環境の構築
  5. PostgreSQL 環境の構築
  6. データの永続化と init スクリプトの挙動
  7. 停止・削除コマンド早見表
  8. トラブルシューティング
  9. 3 行で動作確認

この記事でできること

項目 MySQL PostgreSQL
DB バージョン 8.4 16(Alpine イメージ)
接続確認 mysql クライアント psql クライアント
サンプルテーブル demo_greeting demo_greeting
データ永続化 Docker ボリューム Docker ボリューム
初期 SQL init/ 配下 init/ 配下

前提条件

  • Docker Desktop(Windows / macOS)または Docker Engine + Compose プラグイン(Linux)
  • ターミナルで docker compose が使えること
  • 本リポジトリ(DB_SQL)をクローン済みであること

Windows なら PowerShell でも動きますが、パスでつまずきやすいので WSL か Git Bash の方が楽です。以降、クローンした DB_SQL のルートを $DB_SQL と書きます(実在の環境変数ではなく、置き場所の略記です)。

# Git Bash の例cd /c/path/to/DB_SQL/MySQL_setup# WSL の例cd /mnt/c/path/to/DB_SQL/PostgreSQL_setup# macOS / Linux の例cd ~/src/DB_SQL/PostgreSQL_setup
cd C:\path\to\DB_SQL\MySQL_setup

docker compose は、docker-compose.yml があるフォルダ(MySQL_setupPostgreSQL_setup)で実行します。


全体像:2 つのセットアップの共通設計

フォルダは分かれていますが、中身の組み立て方は揃えてあります。

MySQL_setup/  または  PostgreSQL_setup/├── docker-compose.yml   # コンテナ定義├── .env.example         # 環境変数のひな形├── .env                 # 実際の設定(Git 管理外)├── init/│   └── 01-sample.sql    # 初回起動時だけ実行される SQL├── README.md└── DOCKER.md
flowchart LR  A["docker compose up -d"] --> B["ヘルスチェック healthy"]  B --> C["init/ SQL 実行(初回のみ)"]  C --> D["mysql / psql で接続"]  D --> E["demo_greeting 確認"]

使っているのはだいたい次のとおりです。

  1. 公式イメージ(mysql:8.4 / postgres:16-alpine
  2. 名前付きボリュームでデータ保持
  3. init//docker-entrypoint-initdb.d にマウント(空のボリュームで初回起動したときだけ SQL が走る)
  4. ヘルスチェックで ready になるまで待つ

ここが一番ハマりどころです。init/01-sample.sql を直しても反映されないときは、だいたい古いボリュームが残っています。やり直すなら docker compose down -v のあとで up -d してください。

同時起動について

組み合わせ 結果
MySQL_setup + PostgreSQL_setup 同時に起動できる(既定が 3306 と 5432)
PostgreSQL_setup + 別 Compose(同じく 5432) 競合する。片方を stop/downするか、.env でポート変更
MySQL_setup + ホストの MySQL(3306) 競合しうる。.envMYSQL_PORT を変更

MySQL 環境の構築

1. 作業ディレクトリへ移動

cd $DB_SQL/MySQL_setup

2. 環境変数ファイルを用意

cp .env.example .env
Copy-Item .env.example .env

3. 接続情報(演習用デフォルト)

項目
root パスワード root_practice
ユーザー practice
パスワード practice
データベース practice_db
ポート 3306

演習用の弱いパスワードです。本番や共有環境では使わず、.env は Git に入れない前提です。

3306 が埋まっているときは .envMYSQL_PORT=3307 などに変えます。

4. 起動

docker compose up -ddocker compose ps

うまくいくと、コンテナ mysql-setup-dbUp (healthy) になり、PORTS に 0.0.0.0:3306->3306/tcp が見えます(ポートを変えた場合は .env の値)。

starting のままなら少し待つか、ログを見ます。

docker compose logs db

5. 接続と動作確認

healthy になってから:

docker compose exec db mysql -u practice -ppractice practice_db

mysql> が出たら:

SHOW TABLES;SELECT * FROM demo_greeting;

demo_greeting に 1 行あり、messageHello MySQL なら OK です。抜けるときは exit

6. ワンライナーでの確認

docker compose exec db mysql -u practice -ppractice practice_db -e "SELECT NOW();"docker compose exec db mysql -u practice -ppractice practice_db -e "SHOW TABLES;"docker compose exec db mysql -u practice -ppractice practice_db -e "SELECT * FROM demo_greeting;"

7. ホストから接続(任意)

ホストに mysql クライアントがある場合:

mysql -h 127.0.0.1 -P 3306 -u practice -ppractice practice_db

DBeaver や MySQL Workbench なら Host 127.0.0.1、Port 3306、Database practice_db、User / Password practice です。

docker-compose.yml の中身

services:  db:    image: mysql:8.4    container_name: mysql-setup-db    environment:      MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD:-root_practice}"      MYSQL_DATABASE: "${MYSQL_DATABASE:-practice_db}"      MYSQL_USER: "${MYSQL_USER:-practice}"      MYSQL_PASSWORD: "${MYSQL_PASSWORD:-practice}"      TZ: "${TZ:-Asia/Tokyo}"    ports:      - "${MYSQL_PORT:-3306}:3306"    volumes:      - mysql-setup-data:/var/lib/mysql      - ./init:/docker-entrypoint-initdb.d:ro    healthcheck:      test: ["CMD-SHELL", "mysqladmin ping -h localhost -u$$MYSQL_USER -p$$MYSQL_PASSWORD --silent"]      interval: 5s      timeout: 5s      retries: 20      start_period: 20svolumes:  mysql-setup-data:

PostgreSQL 環境の構築

流れは MySQL と同じで、フォルダとクライアントが違うだけです。

1. 作業ディレクトリへ移動

cd $DB_SQL/PostgreSQL_setup

2. 環境変数ファイルを用意

cp .env.example .env

3. 接続情報(演習用デフォルト)

項目
ユーザー practice
パスワード practice
データベース practice_db
ポート 5432

5432 が埋まっているときは .envPOSTGRES_PORT=5433 などに変えます。ホスト上の 5432 は同時に一つしか取れないので、SQL_hands-on など別 Compose が同じポートを使っているときは先に止めるか、ポートをずらしてください。MySQL_setup(3306)とは同時に上げられます。

4. 起動

docker compose up -ddocker compose ps

コンテナ postgresql-setup-dbUp (healthy)、PORTS に 0.0.0.0:5432->5432/tcp が見えれば起動できています。

5. 接続と動作確認

docker compose exec db psql -U practice -d practice_db

practice_db=# が出たら:

\dtSELECT * FROM demo_greeting;

messageHello PostgreSQL の 1 行なら OK。終了は \q

6. ワンライナーでの確認

docker compose exec db psql -U practice -d practice_db -c "SELECT now();"docker compose exec db psql -U practice -d practice_db -c "\dt"docker compose exec db psql -U practice -d practice_db -c "SELECT * FROM demo_greeting;"

疎通だけ見るなら:

docker compose exec db pg_isready -U practice -d practice_db

7. ホストから接続(任意)

psql "postgresql://practice:practice@localhost:5432/practice_db"

PowerShell で URL の @ が邪魔するときは、コンテナ経由にするか次の形にします。

PGPASSWORD=practice psql -h localhost -U practice -d practice_db

docker-compose.yml の中身

services:  db:    image: postgres:16-alpine    container_name: postgresql-setup-db    environment:      POSTGRES_USER: "${POSTGRES_USER:-practice}"      POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-practice}"      POSTGRES_DB: "${POSTGRES_DB:-practice_db}"      TZ: "${TZ:-Asia/Tokyo}"    ports:      - "${POSTGRES_PORT:-5432}:5432"    volumes:      - postgresql-setup-data:/var/lib/postgresql/data      - ./init:/docker-entrypoint-initdb.d:ro    healthcheck:      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]      interval: 5s      timeout: 5s      retries: 10      start_period: 10svolumes:  postgresql-setup-data:

違うのはイメージ、環境変数名(MYSQL_* / POSTGRES_*)、データディレクトリ、ヘルスチェック程度で、init マウントとボリュームという骨格は共通です。


データの永続化と init スクリプトの挙動

操作 データ init/ の再実行
コンテナ再起動 残る されない
docker compose downup -d 残る されない
docker compose down -vup -d 消える 初回として再実行

最初からやり直すときはこれで足ります。

docker compose down -vdocker compose up -d# healthy を確認してから接続

init スクリプトの内容

MySQL(MySQL_setup/init/01-sample.sql):

CREATE TABLE IF NOT EXISTS demo_greeting (  id INT AUTO_INCREMENT PRIMARY KEY,  message VARCHAR(255) NOT NULL,  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);INSERT INTO demo_greeting (message)VALUES ('Hello MySQL');

PostgreSQL(PostgreSQL_setup/init/01-sample.sql):

CREATE TABLE IF NOT EXISTS demo_greeting (  id SERIAL PRIMARY KEY,  message TEXT NOT NULL,  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW());INSERT INTO demo_greeting (message)VALUES ('Hello PostgreSQL');

AUTO_INCREMENTSERIALTIMESTAMPTIMESTAMPTZ など、方言の差もこのサンプルで見比べられます。


停止・削除コマンド早見表

やりたいこと コマンド
止めるだけ docker compose stop
コンテナ削除(データは残す) docker compose down
DB も含めて最初から docker compose down -v

トラブルシューティング

症状 原因 対処
no configuration file provided 作業ディレクトリが違う MySQL_setup / PostgreSQL_setupcd してから実行
port is already allocated 3306 / 5432 が使用中 競合 Compose を stop/down、または .env でポート変更
demo_greeting が無い 以前のボリュームが残っている docker compose down -v 後に再起動
message が README と違う 古いデータがボリュームに残存 同上
Access denied / password authentication failed .env と接続情報の不一致 .env を確認し、必要なら down -v で再作成
STATUS が healthy にならない 起動エラー docker compose logs db でログ確認
Git Bash で cd C:\... が失敗 Windows パスの書き方 /c/... 形式を使う

3 行で動作確認

*_setup フォルダで。2 行目が Up (healthy) になってから 3 行目へ進みます。

PostgreSQL:

docker compose up -ddocker compose psdocker compose exec db psql -U practice -d practice_db -c "SELECT * FROM demo_greeting;"

MySQL:

docker compose up -ddocker compose psdocker compose exec db mysql -u practice -ppractice practice_db -e "SELECT * FROM demo_greeting;"

Hello PostgreSQL / Hello MySQL の 1 行が出れば完了です。

確認の目安:

  • up -d 後に healthy になった
  • practice_db に接続できた
  • demo_greeting のサンプル行が見えた
  • down -v してからやり直せることを一度試した

healthy まで待たずに接続すると失敗しやすいので、そこだけは焦らない方がいいです。up -d のあとはボリュームを消さない限りデータが残る、という点さえ押さえれば、あとは同じ手順の繰り返しになります。

シェア