Docker で MySQL / PostgreSQL の SQL 環境を構築する
手元に MySQL や PostgreSQL を直接入れると、OS ごとに手順が違い、ポートがぶつかったりバージョンが揃わなかったりしやすいです。ここではリポジトリ DB_SQL の MySQL_setup と PostgreSQL_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
目次
- この記事でできること
- 前提条件
- 全体像:2 つのセットアップの共通設計
- MySQL 環境の構築
- PostgreSQL 環境の構築
- データの永続化と init スクリプトの挙動
- 停止・削除コマンド早見表
- トラブルシューティング
- 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_setupcd C:\path\to\DB_SQL\MySQL_setupdocker compose は、docker-compose.yml があるフォルダ(MySQL_setup か PostgreSQL_setup)で実行します。
全体像:2 つのセットアップの共通設計
フォルダは分かれていますが、中身の組み立て方は揃えてあります。
MySQL_setup/ または PostgreSQL_setup/├── docker-compose.yml # コンテナ定義├── .env.example # 環境変数のひな形├── .env # 実際の設定(Git 管理外)├── init/│ └── 01-sample.sql # 初回起動時だけ実行される SQL├── README.md└── DOCKER.mdflowchart LR A["docker compose up -d"] --> B["ヘルスチェック healthy"] B --> C["init/ SQL 実行(初回のみ)"] C --> D["mysql / psql で接続"] D --> E["demo_greeting 確認"]使っているのはだいたい次のとおりです。
- 公式イメージ(
mysql:8.4/postgres:16-alpine) - 名前付きボリュームでデータ保持
init/を/docker-entrypoint-initdb.dにマウント(空のボリュームで初回起動したときだけ SQL が走る)- ヘルスチェックで 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) |
競合しうる。.env で MYSQL_PORT を変更 |
MySQL 環境の構築
1. 作業ディレクトリへ移動
cd $DB_SQL/MySQL_setup2. 環境変数ファイルを用意
cp .env.example .envCopy-Item .env.example .env3. 接続情報(演習用デフォルト)
| 項目 | 値 |
|---|---|
| root パスワード | root_practice |
| ユーザー | practice |
| パスワード | practice |
| データベース | practice_db |
| ポート | 3306 |
演習用の弱いパスワードです。本番や共有環境では使わず、.env は Git に入れない前提です。
3306 が埋まっているときは .env で MYSQL_PORT=3307 などに変えます。
4. 起動
docker compose up -ddocker compose psうまくいくと、コンテナ mysql-setup-db が Up (healthy) になり、PORTS に 0.0.0.0:3306->3306/tcp が見えます(ポートを変えた場合は .env の値)。
starting のままなら少し待つか、ログを見ます。
docker compose logs db5. 接続と動作確認
healthy になってから:
docker compose exec db mysql -u practice -ppractice practice_dbmysql> が出たら:
SHOW TABLES;SELECT * FROM demo_greeting;demo_greeting に 1 行あり、message が Hello 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_dbDBeaver や 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_setup2. 環境変数ファイルを用意
cp .env.example .env3. 接続情報(演習用デフォルト)
| 項目 | 値 |
|---|---|
| ユーザー | practice |
| パスワード | practice |
| データベース | practice_db |
| ポート | 5432 |
5432 が埋まっているときは .env で POSTGRES_PORT=5433 などに変えます。ホスト上の 5432 は同時に一つしか取れないので、SQL_hands-on など別 Compose が同じポートを使っているときは先に止めるか、ポートをずらしてください。MySQL_setup(3306)とは同時に上げられます。
4. 起動
docker compose up -ddocker compose psコンテナ postgresql-setup-db が Up (healthy)、PORTS に 0.0.0.0:5432->5432/tcp が見えれば起動できています。
5. 接続と動作確認
docker compose exec db psql -U practice -d practice_dbpractice_db=# が出たら:
\dtSELECT * FROM demo_greeting;message が Hello 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_db7. ホストから接続(任意)
psql "postgresql://practice:practice@localhost:5432/practice_db"PowerShell で URL の @ が邪魔するときは、コンテナ経由にするか次の形にします。
PGPASSWORD=practice psql -h localhost -U practice -d practice_dbdocker-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 down → up -d |
残る | されない |
docker compose down -v → up -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_INCREMENT と SERIAL、TIMESTAMP と TIMESTAMPTZ など、方言の差もこのサンプルで見比べられます。
停止・削除コマンド早見表
| やりたいこと | コマンド |
|---|---|
| 止めるだけ | docker compose stop |
| コンテナ削除(データは残す) | docker compose down |
| DB も含めて最初から | docker compose down -v |
トラブルシューティング
| 症状 | 原因 | 対処 |
|---|---|---|
no configuration file provided |
作業ディレクトリが違う | MySQL_setup / PostgreSQL_setup に cd してから実行 |
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 のあとはボリュームを消さない限りデータが残る、という点さえ押さえれば、あとは同じ手順の繰り返しになります。