【Docker】MySQL CLI完全ガイド|接続3パターン・mysqldump実戦・CSV取り込み・文字化け回避・mycli/usql・SSHトンネル・エラー対処

Docker

Docker環境のMySQLを操作するとき、多くの入門記事ではphpMyAdminAdminerなどGUIツールの導入が推奨されます。しかし実務ではCLIで直接叩ける方が圧倒的に速く、自動化にも強い——GUIをコンテナに含めない分、メモリも節約できます。

多くの記事はdocker exec -it mysql mysql -u root -pで止まっており、実戦で本当に必要な認証・SQLファイル実行・バックアップ/リストア・CSVインポート/エクスポート・日本語文字化け対策・リモート接続(SSHトンネル)・mycli/usql等の高機能CLI活用・スクリプト自動化・トラブルシューティングまでまとまった情報がほとんどありません。

この記事では、Docker上のMySQL/MariaDBをCLIだけで完結させる完全ガイドとして、接続パターン3種、SQLファイルの実行方法、mysqldumpの実戦オプション、CSV取り込み、日本語文字化けの完全回避mycli/usql/VS Codeによる補完付きCLI体験、自動化スクリプトのパターン、ERROR 2002/1045/2003のトラブル対処まで、2026年の現場で即使える知識を網羅します。

Docker基礎は【Docker】Composeで複数コンテナを連携させる方法【Docker】volumeの使い方とデータ永続化の基本、MySQL基本文法は【SQL】テーブル一覧を取得する方法等で補完できます。

この記事で学べること

  • Docker MySQLへの接続パターン3種(docker exec/host→container/外部クライアント)
  • パスワードを履歴に残さない安全な認証方法(MYSQL_PWD/.my.cnf/secrets)
  • SQLファイル実行の3つの方法(パイプ/リダイレクト/heredoc)
  • mysqldumpの実戦オプション(single-transaction/routines/triggers/gzip)
  • CSVインポートLOAD DATAmysqlimportSELECT INTO OUTFILE
  • 日本語文字化けの完全回避(client/server/database/connection/results)
  • mycli/usqlで補完+シンタックスハイライト付きCLI体験
  • VS CodeのDatabase Client拡張でDocker MySQLに接続する設定
  • SSHトンネル経由で本番のMySQLにローカルから接続する方法
  • 非対話モードでのスクリプト自動化パターン
  • 典型エラー(ERROR 2002/1045/2003)の原因と対処
スポンサーリンク
  1. 30秒クイックスタート:よく使う10コマンド
  2. 接続パターン3種:docker exec/host→container/外部クライアント
    1. パターン①:docker compose exec(最もシンプル)
    2. パターン②:ホストからmysqlクライアントで接続
    3. パターン③:外部クライアント(GUI/他ツール)
  3. 認証とパスワード:履歴に残さない安全な方法
    1. ①MYSQL_PWD環境変数(スクリプト向き)
    2. ②~/.my.cnf(個人開発向き)
    3. ③secretsファイル(compose本番向き)
  4. SQLファイル実行の3つの方法
    1. ①リダイレクトで流し込み
    2. ②sourceコマンドで内部から実行
    3. ③heredoc(スクリプト内インライン)
  5. mysqldumpの実戦オプション:安全かつ高速なバックアップ
    1. 主要オプションの意味
  6. CSVインポート/エクスポート
    1. CSVインポート(LOAD DATA)
    2. mysqlimportコマンド(ファイル名=テーブル名)
    3. CSVエクスポート(SELECT INTO OUTFILE)
    4. パイプでCSV出力(より現代的)
  7. 日本語文字化けを完全回避する
  8. mycli/usql:補完+シンタックスハイライト付きCLI
    1. mycli(MySQL専用)
    2. usql(マルチDB対応・psql風)
    3. VS Code Database Client拡張
  9. スクリプト自動化:非対話モードのベストプラクティス
  10. SSHトンネル:本番MySQLにローカルから安全接続
  11. よくあるエラーと対処
    1. ERROR 2002 (HY000): Can’t connect via socket
    2. ERROR 1045 (28000): Access denied
    3. ERROR 2003 (HY000): Can’t connect to MySQL server
    4. the input device is not a TTY
    5. 文字化け(????)が表示される
  12. MariaDB CLIとの違い
  13. よくある質問
  14. 関連記事
  15. まとめ

30秒クイックスタート:よく使う10コマンド

まずは頻出コマンドを一覧で。詳細は後続セクションで深掘りします。

やりたいこと コマンド
対話的にMySQLに入る docker compose exec db mysql -u root -p
ワンライナーでSQL実行 docker compose exec db mysql -uroot -proot -e "SHOW DATABASES"
SQLファイルをインポート docker compose exec -T db mysql -uroot -proot mydb < init.sql
ダンプ(バックアップ) docker compose exec db mysqldump -uroot -proot mydb > backup.sql
ホストからmysqlクライアント mysql -h 127.0.0.1 -P 3306 -u root -p
コンテナ内シェル起動 docker compose exec db bash
プロセス確認 docker compose exec db mysqladmin -uroot -proot processlist
テーブル全件件数 mysql -e "SELECT table_name, table_rows FROM information_schema.tables"
CSVインポート docker compose exec db mysqlimport --local mydb users.csv
MySQL停止時のエラーログ docker compose logs db

非対話モードの鍵は-Tフラグdocker compose exec -T db mysql ... < file.sqlのようにパイプ/リダイレクトと組み合わせる時はTTYを無効化(-T)が必要。これを忘れるとthe input device is not a TTYエラーで止まります。

接続パターン3種:docker exec/host→container/外部クライアント

Docker MySQLへの接続には3つの主なパターンがあり、それぞれ用途が違います。

パターン①:docker compose exec(最もシンプル)

コンテナ内でmysqlクライアント起動
# 対話モード
docker compose exec db mysql -u root -p

# データベース指定+ワンライナー
docker compose exec db mysql -u root -proot mydb -e "SHOW TABLES"

# ストリーム入力(SQLファイル流し込み)
docker compose exec -T db mysql -u root -proot mydb < schema.sql

# MySQL 8.0 以降ならcharset明示
docker compose exec db mysql --default-character-set=utf8mb4 -u root -p mydb

docker execとdocker compose execの違い

docker execはコンテナ名を直接指定(docker exec -it mysql_container mysql ...)、docker compose execはcompose.ymlのサービス名を指定(docker compose exec db mysql ...)。後者の方がコンテナ名の変動に強いproject-db-1のような自動生成名を気にせず済む)ため、compose運用ではdocker compose execを推奨。

パターン②:ホストからmysqlクライアントで接続

compose.ymlでポート公開
services:
  db:
    image: mysql:8.0
    ports:
      - "3306:3306"         # ホストの3306に公開
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: mydb
ホスト側mysqlクライアントから接続
# 事前にmysql-clientをインストール(Mac)
brew install mysql-client

# ホストから接続(-h 必須、-P 付きポート指定)
mysql -h 127.0.0.1 -P 3306 -u root -p

# 注意:MySQLは"localhost"指定だとUnix socket探しに行く
# → 127.0.0.1 や IPアドレス指定が必須

3306ポートを公開するリスク:本番サーバーやクラウド環境ではホストポート公開が外部からの攻撃経路になります。ローカル開発でのみ使用し、本番はports:を外すか127.0.0.1:3306:3306でloopbackバインドに制限してください。

パターン③:外部クライアント(GUI/他ツール)

外部GUIツール使用例

  • TablePlus(Mac/Win):有料だが軽量+日本語OK
  • DBeaver(Mac/Win/Linux):無料+多DB対応
  • VS Code “Database Client”拡張:エディタ統合
  • MySQL Workbench:公式+無料
  • mycli / usql:CLIだが補完+ハイライト付き(次章で詳解)

認証とパスワード:履歴に残さない安全な方法

mysql -u root -pPasswordのようにコマンドラインにパスワードを書くとshell履歴とプロセスリストに残りセキュリティリスク。以下の代替手段を使いましょう。

①MYSQL_PWD環境変数(スクリプト向き)

環境変数でパスワード渡し
# スクリプトでパスワードをenv経由
export MYSQL_PWD=root
mysql -u root mydb -e "SELECT * FROM users"

# Docker内部で使う場合
docker compose exec -T db bash -c \
  "MYSQL_PWD=root mysql -u root mydb -e 'SELECT COUNT(*) FROM users'"

# 警告抑制(警告メッセージがうざい場合)
export MYSQL_PWD=root
mysql -u root 2>/dev/null

②~/.my.cnf(個人開発向き)

.my.cnfでデフォルト認証
# ~/.my.cnf(chmod 600必須)
[client]
user=root
password=root
host=127.0.0.1
port=3306
default-character-set=utf8mb4
使い方
chmod 600 ~/.my.cnf

# 以降パスワード不要
mysql
mysql -e "SHOW DATABASES"

# 別ファイルを指定したい場合
mysql --defaults-file=./my.cnf -e "SELECT 1"

③secretsファイル(compose本番向き)

compose.yml + secrets
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root
      MYSQL_DATABASE: mydb
    secrets:
      - mysql_root

secrets:
  mysql_root:
    file: ./secrets/mysql_root.txt      # .gitignore対象

shell履歴からパスワードを削除:誤ってmysql -pMyPasswordを打ってしまったら、history -d <番号>(bash)やhistoryの該当行を手動編集して消去してください。HISTFILE=/dev/nullで一時的に履歴を切るのも有効。

SQLファイル実行の3つの方法

①リダイレクトで流し込み

stdin経由
# もっとも一般的なやり方
docker compose exec -T db mysql -u root -proot mydb < schema.sql

# gz圧縮ファイルからそのまま
gunzip -c backup.sql.gz | docker compose exec -T db mysql -u root -proot mydb

# 複数ファイルを連結して流す
cat 01_schema.sql 02_seed.sql 03_views.sql | \
  docker compose exec -T db mysql -u root -proot mydb

②sourceコマンドで内部から実行

mysqlプロンプト内で読み込み
# ファイルをコンテナにコピーしてから
docker compose cp ./schema.sql db:/tmp/
docker compose exec db mysql -u root -proot mydb -e "source /tmp/schema.sql"

# 対話モード内で
docker compose exec db mysql -u root -proot mydb
mysql> source /tmp/schema.sql
mysql> \. /tmp/schema.sql          # ショートカット

③heredoc(スクリプト内インライン)

heredocで埋め込み
#!/usr/bin/env bash
# scripts/setup-db.sh
set -euo pipefail

docker compose exec -T db mysql -u root -proot <<EOF
CREATE DATABASE IF NOT EXISTS mydb CHARACTER SET utf8mb4;
USE mydb;

CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100),
  email VARCHAR(255) UNIQUE
) ENGINE=InnoDB;

INSERT INTO users (name, email) VALUES ('Taro', 'taro@example.com');
EOF

echo "Database initialized successfully"

compose.ymlの/docker-entrypoint-initdb.d/マウントで初回起動時のSQLファイル自動実行も可能。volumes: ["./init:/docker-entrypoint-initdb.d:ro"]と書けば./init/配下のSQLファイルが自動流し込みされます(データディレクトリが空の初回のみ)。

mysqldumpの実戦オプション:安全かつ高速なバックアップ

素のmysqldump長時間テーブルロックでサービス停止を招くことも。実戦オプションを覚えておくと安全です。

実戦で使うダンプコマンド
# 基本(InnoDB+ロックフリー+ルーチン・トリガー込み)
docker compose exec db mysqldump \
  -u root -proot \
  --single-transaction \
  --routines --triggers --events \
  --set-gtid-purged=OFF \
  mydb > backup_$(date +%Y%m%d).sql

# 圧縮(サイズ削減)
docker compose exec db mysqldump -u root -proot --single-transaction mydb | \
  gzip > backup_$(date +%Y%m%d).sql.gz

# 全DB一括(運用サーバー向け)
docker compose exec db mysqldump -u root -proot \
  --single-transaction --all-databases \
  --routines --triggers --events \
  > all_backup.sql

# スキーマのみ(データなし)
docker compose exec db mysqldump -u root -proot --no-data mydb > schema.sql

# データのみ(スキーマなし)
docker compose exec db mysqldump -u root -proot --no-create-info mydb > data.sql

# 特定テーブルのみ
docker compose exec db mysqldump -u root -proot mydb users orders > partial.sql

# WHERE条件付き(最近30日分だけ)
docker compose exec db mysqldump -u root -proot mydb events \
  --where="created_at >= NOW() - INTERVAL 30 DAY" > recent.sql

主要オプションの意味

オプション 効果
--single-transaction InnoDBでロック無しダンプ(必須)
--routines ストアドプロシージャ/関数を含める
--triggers トリガーを含める
--events イベントスケジューラを含める
--set-gtid-purged=OFF 他環境インポート時のGTIDエラー回避
--quick 大量行を省メモリで処理(デフォルトON)
--column-statistics=0 MySQL 8.0+の列統計を無効(古い版へ移行時)
リストア(インポート)
# 基本
docker compose exec -T db mysql -u root -proot mydb < backup.sql

# gzip圧縮ファイルから
gunzip -c backup.sql.gz | docker compose exec -T db mysql -u root -proot mydb

# 進捗表示したい場合(pv併用)
pv backup.sql | docker compose exec -T db mysql -u root -proot mydb

# 大規模データの高速化設定(インポート中のみ無効化)
docker compose exec -T db mysql -u root -proot <<EOF
SET FOREIGN_KEY_CHECKS=0;
SET UNIQUE_CHECKS=0;
SET AUTOCOMMIT=0;
source /path/to/backup.sql;
COMMIT;
SET FOREIGN_KEY_CHECKS=1;
SET UNIQUE_CHECKS=1;
EOF

CSVインポート/エクスポート

CSVインポート(LOAD DATA)

LOAD DATAでCSV取り込み
# CSVファイルをコンテナにコピー
docker compose cp ./users.csv db:/tmp/

# コンテナ内からLOAD DATA
docker compose exec db mysql -u root -proot mydb <<EOF
LOAD DATA INFILE '/tmp/users.csv'
INTO TABLE users
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\\n'
IGNORE 1 ROWS                   -- ヘッダー行スキップ
(name, email, created_at);
EOF

# LOCALキーワードでホストから直接(--local-infile=1が必要)
docker compose exec -T db mysql --local-infile=1 -u root -proot mydb <<EOF
LOAD DATA LOCAL INFILE '/path/inside/container/users.csv'
INTO TABLE users
FIELDS TERMINATED BY ','
IGNORE 1 ROWS;
EOF

mysqlimportコマンド(ファイル名=テーブル名)

mysqlimport
# ファイル名"users.csv"→"users"テーブルに自動マップ
docker compose cp ./users.csv db:/tmp/
docker compose exec db mysqlimport \
  --fields-terminated-by="," \
  --lines-terminated-by="\n" \
  --ignore-lines=1 \
  -u root -proot mydb /tmp/users.csv

CSVエクスポート(SELECT INTO OUTFILE)

OUTFILEで出力
docker compose exec db mysql -u root -proot mydb <<EOF
SELECT * FROM users
INTO OUTFILE '/tmp/users_export.csv'
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\\n';
EOF

# ホストへ取り出し
docker compose cp db:/tmp/users_export.csv ./

パイプでCSV出力(より現代的)

mysql –batch でTSV→CSV変換
# --batch で TSV形式出力
docker compose exec db mysql -u root -proot mydb --batch -e \
  "SELECT name, email FROM users" | \
  sed 's/\t/,/g' > users_export.csv

# もう少し安全(ヘッダー付き+CSV escape)
docker compose exec db mysql -u root -proot mydb --batch --quick \
  -e "SELECT name, email FROM users" \
  | python3 -c \
  "import csv, sys; w=csv.writer(sys.stdout); [w.writerow(line.split(chr(9))) for line in sys.stdin]" \
  > users_export.csv

secure_file_privの罠:MySQL 8.0以降はsecure-file-priv/var/lib/mysql-files/等に制限されており、INTO OUTFILEの出力先が限定されます。エラー時はSHOW VARIABLES LIKE 'secure_file_priv';で許可ディレクトリを確認し、そのパスに出力 → docker compose cpで取り出し、が安全な手順です。

日本語文字化けを完全回避する

Docker MySQLで日本語が?????になる、データは見えるがソートが変、等はcharacter_setcollationの設定不足が原因。5箇所すべてをutf8mb4で揃えるのが正解です。

compose.yml(文字コード完全設定)
services:
  db:
    image: mysql:8.0
    command: >
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
      --skip-character-set-client-handshake
    environment:
      MYSQL_DATABASE: mydb
      MYSQL_ROOT_PASSWORD: root
      LANG: C.UTF-8
      LC_ALL: C.UTF-8
    volumes:
      - db_data:/var/lib/mysql
      - ./my.cnf:/etc/mysql/conf.d/custom.cnf:ro

volumes:
  db_data:
my.cnf(追加調整)
[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
skip-character-set-client-handshake
確認コマンド
# 現在の文字コード設定を確認
docker compose exec db mysql -u root -proot -e \
  "SHOW VARIABLES LIKE 'character_set%'; SHOW VARIABLES LIKE 'collation%';"

# 結果例(全てutf8mb4になっているべき)
# character_set_client     utf8mb4
# character_set_connection utf8mb4
# character_set_database   utf8mb4
# character_set_results    utf8mb4
# character_set_server     utf8mb4

utf8 vs utf8mb4の違い

MySQLのutf8実は3バイト制限で絵文字/特殊Unicodeが保存できません。必ずutf8mb4(4バイト対応)を使います。MySQL 8.0ではデフォルトutf8mb4ですが、古いDBから移行した環境はutf8mb3(旧utf8相当)になっていることがあるのでSHOW CREATE TABLEで確認を。

mycli/usql:補完+シンタックスハイライト付きCLI

標準のmysqlクライアントは補完もハイライトもなく、打ち間違いが多発。mycliまたはusqlに置き換えると体験が劇的に向上します。

mycli(MySQL専用)

mycli導入+接続
# インストール(Mac/Linux)
brew install mycli            # macOS
pip install mycli              # Python環境

# Docker MySQLに接続(ホスト経由)
mycli -h 127.0.0.1 -P 3306 -u root -p mydb

# 機能
# - スマート自動補完(テーブル名・カラム名・キーワード)
# - シンタックスハイライト
# - マルチライン編集
# - 履歴検索(Ctrl+R)

usql(マルチDB対応・psql風)

usqlでMySQL/PostgreSQL/Oracle等すべて統一
# インストール
brew install xo/xo/usql       # macOS

# URL形式で接続
usql mysql://root:root@127.0.0.1:3306/mydb
usql postgres://user:pass@localhost/db
usql sqlite3:./local.db

# コマンド
\d users          # テーブル構造表示(psql風)
\dt               # テーブル一覧
\dn               # データベース一覧
\i schema.sql     # SQLファイル実行
\q                # 終了

複数DB触る人はusql一択。同じコマンド(\dt, \d table)がMySQL/PostgreSQL/Oracle/SQLiteで使えるため、頭を切り替えずに済みます。mycliはMySQL特化の完成度が高いので、単一DBしか触らない人に推奨。

VS Code Database Client拡張

拡張インストール+接続設定
# 1. 拡張インストール
#    Database Client (cweijan.vscode-mysql-client2)

# 2. 左サイドバーのDatabaseアイコン → Add Connection
#    Type: MySQL
#    Host: 127.0.0.1
#    Port: 3306
#    User: root
#    Password: root

# 3. 機能
#    - テーブル一覧/スキーマGUI表示
#    - .sql ファイルから直接実行(Ctrl+Alt+E)
#    - 結果をCSV/JSONエクスポート
#    - ER図生成

スクリプト自動化:非対話モードのベストプラクティス

マイグレーション自動実行スクリプト
#!/usr/bin/env bash
# scripts/migrate.sh
set -euo pipefail

DB_NAME="${DB_NAME:-mydb}"
DB_USER="${DB_USER:-root}"
DB_PASS="${DB_PASS:-root}"
MIGRATIONS_DIR="./migrations"

# Docker composeが起動しているか確認
if ! docker compose ps db | grep -q "running"; then
  echo "Starting DB container..."
  docker compose up -d db
  # healthcheck待機
  until docker compose exec db mysqladmin ping -h localhost --silent; do
    echo "Waiting for DB..."
    sleep 2
  done
fi

# migrations ディレクトリのSQLを順次実行
for file in $(ls $MIGRATIONS_DIR/*.sql | sort); do
  echo "Applying: $file"
  docker compose exec -T db mysql \
    -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" < "$file"
done

echo "Migration complete"
日次バックアップcron向けスクリプト
#!/usr/bin/env bash
# scripts/backup-daily.sh
set -euo pipefail

BACKUP_DIR="./backups"
DATE=$(date +%Y%m%d_%H%M)
FILENAME="$BACKUP_DIR/mydb_$DATE.sql.gz"

mkdir -p $BACKUP_DIR

# ダンプ+gzip
docker compose exec -T db mysqldump \
  --single-transaction \
  --routines --triggers --events \
  -u root -proot mydb | gzip > "$FILENAME"

# 7日以上前のバックアップを削除
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete

echo "Backup saved: $FILENAME"

crontab登録例

0 3 * * * cd /path/to/project && ./scripts/backup-daily.sh >> /var/log/mysql-backup.log 2>&1(毎日03:00に実行、ログ出力)。CIサーバー/本番でも同じパターンで運用できます。GitHub Actions で定期バックアップを回す方法は【GitHub】Actions完全ガイドのschedule(cron)セクションを参照。

SSHトンネル:本番MySQLにローカルから安全接続

本番サーバーのMySQLを直接外部公開せず、SSHトンネル経由で安全にローカルクライアントから接続するパターン。

SSHトンネルを張って接続
# トンネル開設(ローカル13306 → サーバーSSH経由 → DBの3306)
ssh -N -L 13306:localhost:3306 user@prod-server.example.com &

# ローカルからmysqlクライアントで接続
mysql -h 127.0.0.1 -P 13306 -u root -p

# mycliで接続(より快適)
mycli -h 127.0.0.1 -P 13306 -u root -p

# 終了時(バックグラウンドプロセス停止)
kill %1
~/.ssh/config で簡略化
# ~/.ssh/config
Host prod-db
  HostName prod-server.example.com
  User deploy
  IdentityFile ~/.ssh/deploy_key
  LocalForward 13306 localhost:3306

# 以降
ssh -N prod-db &
mysql -h 127.0.0.1 -P 13306 -u root -p

本番DBにSELECT以外のクエリを投げる際は必ずトランザクション開始+即ROLLBACK練習の上で。UPDATEを条件忘れてWHEREなしで実行すると全件書き換わる事故が起きます。SET autocommit=0;を先に実行する習慣をつけましょう。

よくあるエラーと対処

ERROR 2002 (HY000): Can’t connect via socket

原因:MySQLが”localhost”をUnix socket接続と解釈してソケットファイルを探しに行く。対処:-h 127.0.0.1IP指定に変える(TCP/IP接続になる)。--protocol=tcpオプションでも強制可能。

ERROR 1045 (28000): Access denied

認証失敗の診断
# 原因1: パスワード間違い
# 原因2: 接続元ホスト制限(root@'localhost'のみ許可等)
# 原因3: MySQL 8のデフォルト認証プラグイン

# ユーザー一覧と接続元を確認
docker compose exec db mysql -u root -proot <<EOF
SELECT user, host, plugin FROM mysql.user;
EOF

# 外部接続も許可('%' ワイルドカード)
docker compose exec db mysql -u root -proot <<EOF
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
FLUSH PRIVILEGES;
EOF

ERROR 2003 (HY000): Can’t connect to MySQL server

原因:ポート未公開/firewall/コンテナ停止。対処:docker compose psでdbが”running”か確認、②docker compose logs dbでエラー探す、③compose.ymlでports: ["3306:3306"]の公開漏れ、④docker compose exec db mysqladmin pingで疎通確認。

the input device is not a TTY

-Tオプションで解決
# NG:パイプ/リダイレクト時に-tが邪魔
docker compose exec db mysql -u root -p mydb < backup.sql

# OK:-T で TTY無効化
docker compose exec -T db mysql -u root -proot mydb < backup.sql

# 注:docker run / docker exec も同じく -i と -t の使い分けに注意

文字化け(????)が表示される

5箇所の文字コード整合がポイント(client/connection/database/results/server)。すべてutf8mb4で揃えてください。本記事「日本語文字化けを完全回避する」セクションのcompose.yml+my.cnf設定を適用。

MariaDB CLIとの違い

MariaDBはMySQL互換として設計されていますが、クライアント側にも細かい差異があります。

項目 MySQL MariaDB
バイナリ名 mysql mariadbmysqlもエイリアス)
環境変数 MYSQL_* MARIADB_*MYSQL_*も互換)
ダンプ mysqldump mariadb-dumpmysqldumpエイリアス)
healthcheck mysqladmin ping healthcheck.sh --connect
デフォルト認証 MySQL 8.0+:caching_sha2_password mysql_native_password

よくある質問

QphpMyAdminを使わない理由は?
A①Webサーバー+PHP追加でコンテナが重くなる、②起動のたびにブラウザ開閉が手間、③ CLIの方が再現性のあるスクリプト化に向く、④セキュリティ(公開ポート増える)、⑤mycliやVS Code Database Clientの方が快適。ただしチーム非エンジニアに操作させるときはphpMyAdmin/Adminerの方が敷居が低いため、用途で使い分けます。
Qdocker exec と docker compose exec の違い
Adocker execコンテナ名直接指定docker exec -it my_db mysql ...)、docker compose execサービス名指定docker compose exec db mysql ...)。後者はproject-db-1のようなcompose自動生成名を気にせず済むためcompose運用では後者を推奨。
QSQLファイルを流し込むと”input device is not a TTY”
A-TオプションでTTY割り当てを無効化してください。docker compose exec -T db mysql -u root -proot mydb < backup.sql。パイプ/リダイレクトと一緒に使う時は必須です。
QMySQL 8.0でrootのパスワードを変更したい
AALTER USER 'root'@'localhost' IDENTIFIED BY 'newpass';を実行後FLUSH PRIVILEGES;。compose.ymlのMYSQL_ROOT_PASSWORD初回データ作成時のみ有効なので、後から変えても反映されません。DB再初期化が必要な場合はdocker compose down -vでvolume削除してから再起動。
Qホストのmysqlコマンドでlocalhostに繋がらない
AMySQLのlocalhostUnix socket接続を試みるため、Dockerのネットワークでは失敗します。-h 127.0.0.1(IP指定)または--protocol=tcpを指定してください。これは本記事「ERROR 2002」の解説でも扱っています。
Q大量データを高速でインポートしたい
ASET FOREIGN_KEY_CHECKS=0;SET UNIQUE_CHECKS=0;で制約チェック一時無効化、②--quickオプション、③innodb_flush_log_at_trx_commit=0で一時的に書き込み緩和、④複数ファイルの並列実行、⑤インデックス作成はインポート後。詳細は本記事「mysqldumpの実戦オプション」→「リストア」セクション参照。
Qmycliとusqlどちらがおすすめ?
AMySQLしか触らない人はmycli(MySQL特化の完成度)、複数DB(MySQL/PostgreSQL/Oracle)を触る人はusql(統一コマンド)。どちらもbrew installで入るので両方試すのもおすすめ。
Q本番MySQLにローカルから安全に接続したい
ASSHトンネルが定番。ssh -N -L 13306:localhost:3306 user@prod-server &でポート転送、その後mysql -h 127.0.0.1 -P 13306で接続。本記事「SSHトンネル」セクションで~/.ssh/config設定込みで解説しています。本番操作は必ずSELECTのみから始め、更新はBEGIN;ROLLBACK練習を。
Q日本語が文字化けする
A5箇所(client/connection/database/results/server)を全てutf8mb4で統一。compose.ymlのcommand:セクションと/etc/mysql/conf.d/マウントで設定します。詳しくは本記事「日本語文字化けを完全回避する」セクション参照。

関連記事

まとめ

  • 接続は3パターンdocker compose exec/ホストからmysql -h/GUI外部ツール
  • パイプ・リダイレクトは-Tフラグ必須(TTY無効化)
  • パスワードはMYSQL_PWD~/.my.cnf/secretsで履歴に残さない
  • ダンプの必須オプション:--single-transaction --routines --triggers --events --set-gtid-purged=OFF
  • CSV取り込みはLOAD DATA INFILEmysqlimportsecure_file_privの制限に注意)
  • 日本語文字化けは5箇所すべてutf8mb4で完全回避
  • CLIを格上げするならmycli(MySQL特化)/usql(多DB統一)
  • VS Code Database Client拡張でエディタ統合も便利
  • 自動化:migrate.shbackup-daily.shパターン+crontabまたはGitHub Actionsで定期実行
  • 本番接続はSSHトンネル(~/.ssh/configでLocalForward
  • ERROR 2002=IP指定/1045=認証・権限/2003=ポート・firewall/TTYエラー=-T

phpMyAdminを使わないCLI運用は、習得コストを数時間で回収できる生産性投資です。バックアップ・マイグレーション・CSV取り込みをスクリプト化すれば、チーム全員が同じコマンド一発で確実な操作を実行でき、GUIの手順書メンテナンスから解放されます。mycli/usql+VS Code拡張を組み合わせれば、GUI並みの快適さでより軽量・再現性の高い開発環境が手に入ります。基礎的なDocker運用はCompose連携、永続化はvolume、WordPressと組み合わせるならWordPress Dockerも併せてご活用ください。