Docker 入門
MySQL サーバを Docker で構築する
Docker で MySQL サーバを起動する
MySQL サーバを構築し日本語化する
ここでは Docker で MySQL サーバを起動するサンプルを示します.MySQL のコンテナの設定は多くの Web サイトでも公開されていますが,日本語表示で文字化けすることがしばしばです.ここでは日本語化の設定を自動的に行うこととします.なお,このページのサンプルコードは GitHub の MySQL01 フォルダで公開しています.まず,新規ディレクトリの中に次のディレクトリ,ファイル構成を作成します.
% tree -a -F ⏎
./
├── .env
├── .env.example
├── .gitignore
├── docker-compose.yml
├── mysql/
│ ├── Dockerfile
│ ├── my.cnf
│ ├── script/
│ │ └── init-db.sql
│ └── sql/
│ ├── 01-show.sql
│ ├── 02-create.sql
│ ├── 03-showtables.sql
│ ├── 04-desc.sql
│ ├── 05-insert.sql
│ ├── 06-select.sql
│ └── 07-select.sql
└── Readme.md
4 directories, 15 files
全体の設計図である docker-compose.yml は次の内容にします.まず,21〜22行目にボリュームの記述があることに注意してください.これによりデータベースのデータはコンテナ内部ではなく,ローカル環境の特定の場所に(コンテナの状態とは独立して)永続的に保存されることになります.一方で,MySQL については5行目で Dockerfile のパスが指定されており,この Dockerfile を用いてイメージがビルドされます.このとき,Intel CPUのマシンであるか Apple Silicon のマシンであるかによってベースとして利用する Docker イメージが異なります.これは .env ファイルに記述します.
docker-compose.yml
services:
mysql:
build:
context: .
dockerfile: ./mysql/Dockerfile
args:
IMAGE: ${MYSQL_IMAGE}
container_name: mysql9
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
- mysqlvolume:/var/lib/mysql
- ./mysql/script:/docker-entrypoint-initdb.d
- ./mysql/sql:/sql
ports:
- 3306:3306
volumes:
mysqlvolume:
Intel ,Apple Silicon のいずれのチップをマシンが搭載しているかで利用する Docker イメージが異なります.この情報は .env ファイルに記述します.また,MySQL 接続時のパスワードも .env に記述します.なお,行頭に #
を入力するとその行はコメントアウトされます.Intel の場合は1行目を有効に(2行目をコメントアウト)し,Apple Silicon の macOS では2行目を有効にしてください.また,管理者 (root ユーザ) のパスワードと docker-user 用のパスワードにはもちろん複雑な文字列を指定してください.ここで指定したパスワードが MySQL の管理者や docker-user のパスワードとして docker-compose.yml の10〜12行目で読み込まれて設定されることになります.
.env
# MYSQL_IMAGE=mysql:9.4
MYSQL_IMAGE=arm64v8/mysql:9.4
MYSQL_ROOT_PASSWORD=password
MYSQL_USER=docker-user
MYSQL_PASSWORD=secret
上のように,.env にはパスワードなどの機密情報を入力することになります.したがって,.env が Git のリポジトリに含まれないように .gitignore には次の内容を記述します.
.gitignore
.env
しかしながら,別のマシンで GitHub からクローンを作成したときには .env がリポジトリに含まれていないため,.env にどのような設定をすれば良いかが分からなくなります.しばしば .env.example などを作成しておき,.env のひな形とする方法が採用されます.このファイルには機密情報を記載しないように注意して Git のリポジトリに含めておくと良いでしょう.
.env.example
MYSQL_IMAGE=mysql:9.4
# MYSQL_IMAGE=arm64v8/mysql:9.4
MYSQL_ROOT_PASSWORD=
MYSQL_USER=docker-user
MYSQL_PASSWORD=
次に MySQL イメージをビルドするための Dockerfile を次のとおり作成します.ここで,1行目は docker-compose.yml の7行目を参照し,.env ファイルに設定された MYSQL_IMAGE
の設定を読み込むことを意味しています.そして,Dockerfile の3行目ではそのイメージを利用してビルドすることを指示しています.5行目では必要なライブラリをインストールした上で,8〜11行目で日本語化の設定を行っています.
mysql/Dockerfile
ARG IMAGE
FROM ${IMAGE}
RUN microdnf install -y glibc-locale-source glibc-langpack-en && \
microdnf clean all
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG="ja_JP.UTF-8" \
LANGUAGE="ja_JP:ja" \
LC_ALL="ja_JP.UTF-8"
MySQL の設定ファイル mysql/my.cnf では文字コードを指定して,日本語文字列で文字化けが起こらないようにしています.
mysql/my.cnf
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
[client]
default-character-set=utf8mb4
後の作業でコマンド docker-compose up -d
を初めて実行したときには,mysqlvolume
が生成され,データベースが作成,ユーザとパスワードが登録されます.このときに管理したいデータベースも作成することができます.データベースの作成と権限付与は次のスクリプトで行います.具体的には commentsDB
という名称のデータベースを作成し,docker-user
というユーザにデータベース commentsDB
へのすべてのアクセス権限を付与しています.さらに他のデータベースも作成したい場合は CREATE DATABASE ...
と GRANT ALL ...
の2行をペアでこのファイルの最後に追加すると良いでしょう.
mysql/script/init-db.sql
CREATE DATABASE IF NOT EXISTS `commentsDB`;
GRANT ALL PRIVILEGES ON `commentsDB`.* TO 'docker-user';
ここまでの作業ができれば,コンテナを起動することができます.なお,初回の起動時には Dockerfile の指定に従って,イメージのダウンロードやビルド,各種の設定を行うために少々時間を要することになるでしょう.実行結果の最後には,イメージのビルドが完了し,ネットワークとボリュームが新規に作成され,コンテナが起動したことが示されているので,注意深く内容を確認して理解してください.
% docker compose up -d ⏎ [+] Building 56.4s (10/10) FINISHED => [internal] load local bake definitions 0.0s => => reading from stdin 685B 0.0s => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 351B 0.0s => WARN: InvalidDefaultArgInFrom: Default value for ARG ${IMAGE} results 0.0s => [internal] load metadata for docker.io/arm64v8/mysql:9.4 2.8s => [auth] arm64v8/mysql:pull token for registry-1.docker.io 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [1/3] FROM docker.io/arm64v8/mysql:9.4@sha256:f9b6162105c25376a0fc622 20.3s => => resolve docker.io/arm64v8/mysql:9.4@sha256:f9b6162105c25376a0fc6223 0.0s => => sha256:b5e369658cc0fdedce73e0479a85cd17ba8a09435f 48.09MB / 48.09MB 3.9s => => sha256:254b59ee484a86b0b0143067dc22137b90ccf97360862f80 885B / 885B 0.7s => => sha256:f9b6162105c25376a0fc6223f8a963be4917ebed62cc 1.66kB / 1.66kB 0.0s => => sha256:3c2bfb0b6078896f1716c978953cec2ffc0cbd89 736.81kB / 736.81kB 1.1s => => sha256:9d01c2e753a10a6da7006ad4b46f310c4b5ef3786733 2.87kB / 2.87kB 0.0s => => sha256:e0e732e153ab7fa3d9417e510a440a87b29a08304473 6.54kB / 6.54kB 0.0s => => sha256:875f1cba1a38bbdc6ef3e57ad81bd56778282d2c864b 6.45MB / 6.45MB 1.7s => => sha256:22a8e223d0070e7b6bef1310aadd9ef6551bd921c78d 2.60kB / 2.60kB 1.5s => => sha256:5fef58f279086f4d8484960900d3d1d97d3518ffa4aef816 339B / 339B 1.8s => => sha256:60f9608fedbaeb9ccecdef87af22e12b4344558ee2 48.00MB / 48.00MB 6.0s => => sha256:d83cb00134800127058249e977837ab7cfd87f24b1bdce36 325B / 325B 2.3s => => sha256:6f28acb97b5e468da98c28ab5f837730c307311 167.23MB / 167.23MB 14.3s => => extracting sha256:b5e369658cc0fdedce73e0479a85cd17ba8a09435fc3b21f6 1.0s => => sha256:690842f663f099ddcb38be049f6a987424ac76f2c400 5.33kB / 5.33kB 4.1s => => extracting sha256:254b59ee484a86b0b0143067dc22137b90ccf97360862f80d 0.0s => => extracting sha256:3c2bfb0b6078896f1716c978953cec2ffc0cbd896eac511bf 0.0s => => extracting sha256:875f1cba1a38bbdc6ef3e57ad81bd56778282d2c864b70fa8 0.1s => => extracting sha256:22a8e223d0070e7b6bef1310aadd9ef6551bd921c78d52c7b 0.0s => => extracting sha256:5fef58f279086f4d8484960900d3d1d97d3518ffa4aef816a 0.0s => => extracting sha256:60f9608fedbaeb9ccecdef87af22e12b4344558ee2cb96334 0.7s => => extracting sha256:d83cb00134800127058249e977837ab7cfd87f24b1bdce36e 0.0s => => extracting sha256:6f28acb97b5e468da98c28ab5f837730c30731185e7e51188 5.9s => => extracting sha256:690842f663f099ddcb38be049f6a987424ac76f2c4004a053 0.0s => [2/3] RUN microdnf install -y glibc-locale-source glibc-langpack-en & 32.4s => [3/3] RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 0.6s => exporting to image 0.1s => => exporting layers 0.1s => => writing image sha256:7a4891fb5ab40db5da1c07ab8d246f0edcb325d56c06d2 0.0s => => naming to docker.io/library/mysql01-mysql 0.0s => resolving provenance for metadata file 0.0s [+] Running 4/4 ✔ mysql01-mysql Built 0.0s ✔ Network mysql01_default Created 0.0s ✔ Volume "mysql01_mysqlvolume" Created 0.0s ✔ Container mysql9 Started 0.1s %
コンテナと MySQL へログインする
コンテナが起動していることを確認します.
% docker container ls ⏎
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9cac7220a67b mysql01-mysql "docker-entrypoint.s…" 33 seconds ago Up 32 seconds 0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp mysql9
%
コンテナに接続します.
% docker exec -it mysql9 /bin/bash ⏎
bash-5.1#
コンテナに接続できたので,root ユーザ(管理者)として MySQL にログインしてみます.ここで,-u
はユーザ名の指定で,-p
はパスワードのプロンプトを表示させてそのプロンプトにパスワードを入力するためのオプションです.なお,パスワードは .env ファイルの MYSQL_ROOT_PASSWORD
に記載した内容を入力しなければなりません.パスワードを入力しても画面には一切表示されないことに注意してください.MySQL にログインできたら SHOW DATABASES;
でデータベースの一覧を表示したのちに exit
でログアウトします.
bash-5.1# mysql -u root -p ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎ Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 9.4.0 MySQL Community Server - GPL Copyright (c) 2000, 2025, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> SHOW DATABASES; ⏎ +--------------------+ | Database | +--------------------+ | commentsDB | | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.002 sec) mysql> exit ⏎ Bye bash-5.1#
次に,docker-user というユーザで MySQL にログインします.このときに利用すべきパスワードは .env ファイルの MYSQL_PASSWORD
に記載した文字列であることに注意してください.ログイン後,先ほどと同じようにデータベースの一覧を表示しますが,docker-user にアクセス権限が与えられているデータベースが管理者とは異なることから,表示されるデータベースの数が少なくなっていることに注意してください.つまり,ここの設定で権限が与えられた commentsDB
というデータベースにはアクセスできるものの,mysql
と sys
というデータベースには docker-user がアクセスできないことを意味しています.
bash-5.1# mysql -u docker-user -p ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎ Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 9.4.0 MySQL Community Server - GPL Copyright (c) 2000, 2025, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> SHOW DATABASES; ⏎ +--------------------+ | Database | +--------------------+ | commentsDB | | information_schema | | performance_schema | +--------------------+ 3 rows in set (0.001 sec) mysql> exit ⏎ Bye bash-5.1#
ここまでの作業で,データベースの起動や初期設定ができました.一旦コンテナからログアウトしておきます.
bash-5.1# exit ⏎
%
SQL を準備する
次に,ローカル環境でいくつかの SQL を準備します.まず,データベースの一覧を表示するだけの SQL です.
mysql/sql/01-show.sql
SHOW DATABASES;
データベースにテーブルを作成するための SQL です.この SQL は一度だけ実行することに注意してください.
mysql/sql/02-create.sql
USE commentsDB;
CREATE TABLE IF NOT EXISTS comments (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(20),
body VARCHAR(140)
)
ENGINE=InnoDB CHARACTER SET utf8mb4;
commentDB
というデータベースに作成されているテーブルを一覧で表示する SQL です.
mysql/sql/03-showtables.sql
USE commentsDB;
SHOW tables;
comments
テーブルの定義情報(フィールドの設定など)を確認するための SQL です.
mysql/sql/04-desc.sql
USE commentsDB;
DESC comments;
comments
テーブルに4つのレコードを登録するための SQL です.この SQL も1度だけ実行することに注意してください.
mysql/sql/05-insert.sql
USE commentsDB;
INSERT INTO comments (title, body)
VALUES
('今日の天気', '今日の天気は雨です'),
('明日の天気', '明日の天気も雨でしょう'),
('明日の天気', '明日の天気も晴れでしょう'),
('今日の天気', '今日の天気は晴れです');
comments
テーブルに登録されたレコードを一覧で表示する SQL です.
mysql/sql/06-select.sql
USE commentsDB;
SELECT * FROM comments;
comments
テーブルの body
列で「晴れ」という文字列を検索する SQL です.
mysql/sql/07-select.sql
USE commentsDB;
SELECT * FROM comments WHERE body LIKE '%晴れ%';
コンテナにログインして SQL を実行する
SQL の準備ができたらコンテナにログインし,sql ディレクトリに移動します.なお,ls
や cd
といったコマンドに関する説明はここを参照してください.
% docker exec -it mysql9 /bin/bash ⏎ bash-5.1# ls ⏎ afs boot docker-entrypoint-initdb.d home lib64 mnt proc run sql sys usr bin dev etc lib media opt root sbin srv tmp var bash-5.1# cd sql ⏎ bash-5.1# ls ⏎ 01-show.sql 04-desc.sql 07-select.sql 02-create.sql 05-insert.sql 03-showtables.sql 06-select.sql bash-5.1#
SQL を実行します.まず,01-show.sql を実行してデータベースの一覧を確認します.なお,以降の操作はテキストファイルに記述された SQL 文を実行していますが,mysql に mysql -u docker-user -p
コマンドでログインして同じ SQL を直接入力して実行しても構いません.
bash-5.1# mysql -u docker-user -p < 01-show.sql ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎ Database commentsDB information_schema performance_schema bash-5.1#
次に,02-create.sql を実行してテーブルを作成します.このとき,何も結果が表示されないことに注意してください.
bash-5.1# mysql -u docker-user -p < 02-create.sql ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎ bash-5.1#
03-show.sql を実行してテーブルが正しく作成されているか確認します.
bash-5.1# mysql -u docker-user -p < 03-showtables.sql ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎ Tables_in_commentsDB comments bash-5.1#
04-desc.sql を実行して comments
テーブルの定義を確認します.comments
テーブルには id
, title
, body
という3つのフィールド(列)があることを確認してください.
bash-5.1# mysql -u docker-user -p < 04-desc.sql ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎ Field Type Null Key Default Extra id int unsigned NO PRI NULL auto_increment title varchar(20) YES NULL body varchar(140) YES NULL bash-5.1#
comments
テーブルにデータを登録するために 05-insert.sql を実行します.
bash-5.1# mysql -u docker-user -p < 05-insert.sql ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎ bash-5.1#
登録されたレコードを一覧で確認するために 06-select.sql を実行します.
bash-5.1# mysql -u docker-user -p < 06-select.sql ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎ id title body 1 今日の天気 今日の天気は雨です 2 明日の天気 明日の天気も雨でしょう 3 明日の天気 明日の天気も晴れでしょう 4 今日の天気 今日の天気は晴れです bash-5.1#
最後に 07-select.sql を実行して文字列「晴れ」で検索し,コンテナからログアウトします.
bash-5.1# mysql -u docker-user -p < 07-select.sql ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎ id title body 3 明日の天気 明日の天気も晴れでしょう 4 今日の天気 今日の天気は晴れです bash-5.1# exit ⏎ exit What's next: Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug mysql9 Learn more at https://docs.docker.com/go/debug-cli/ %
docker exec コマンドで MySQL へ直接ログインする
これまでは Windows や macOS のターミナルから一旦コンテナの /bin/bash にログインしてから,mysql にログインしていました.次のコマンドを利用すると,ターミナルから直接コンテナの mysql に接続することができます.ここで,-it mysql9
にある mysql9
は docker-compose.yml の8行目で定義されたコンテナ名で,その直後にある mysql
は実行するコマンドです.
% docker exec -it mysql9 mysql -u docker-user -p ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎
macOS から直接 MySQL にログインする
macOS では次のコマンドで mysql をインストールできます.なお,brew コマンドが使えない場合はこのあたりを参考に Homebrew をインストールしてください.
% brew install mysql ⏎
docker-compose.yml の18〜19行目 にはポート番号の設定があります.このポートを使って直接コンテナと通信することが可能です.なお,-h 127.0.0.1
は localhost を意味する IP アドレスです.-P 3306
でポート番号を指定しています.
% mysql -h 127.0.0.1 -P 3306 -u docker-user -p ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎
この方法を使うと macOS のローカル環境にある SQL 文を直接コンテナで実行してその結果を取得することができるようになります.
% mysql -h 127.0.0.1 -P 3306 -u docker-user -p < ./mysql/sql/07-select.sql ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎ id title body 3 明日の天気 明日の天気も晴れでしょう 4 今日の天気 今日の天気は晴れです %
コンテナを停止してボリュームの存在を確認する
データベースの利用が終わったので,コンテナを停止して破棄してみます.このとき,コンテナ mysql9
とネットワーク mysql01_default
は破棄された (Removed) ものの,ボリュームは破棄されていないことに注意してください.
% docker container ls ⏎ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9cac7220a67b mysql01-mysql "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp mysql9 % % docker compose down ⏎ [+] Running 2/2 ✔ Container mysql9 Removed 1.0s ✔ Network mysql01_default Removed 0.2s % % docker container ls -a ⏎ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES %
ボリュームの一覧を確認するとその存在が確認できました.
% docker volume ls ⏎
DRIVER VOLUME NAME
local mysql01_mysqlvolume
%
もう一度コンテナを起動してみます.設定ファイルに変更を加えていないのですぐに起動します.(一方で Dockerfile に変更を加えた場合など,強制的に再ビルドしたい場合は --build
オプションを付与してください.)
% docker compose up -d ⏎
[+] Running 2/2
✔ Network mysql01_default Created 0.0s
✔ Container mysql9 Started 0.1s
%
一旦コンテナを破棄してイメージからコンテナを再作成しましたが,データベースのデータが格納されているボリュームは削除されていないため,以前に登録したデータがそのまま残っていることに注意してください.
% mysql -h 127.0.0.1 -P 3306 -u docker-user -p < ./mysql/sql/07-select.sql ⏎ Enter password: .env に記載したパスワード(何も表示されない) ⏎ id title body 3 明日の天気 明日の天気も晴れでしょう 4 今日の天気 今日の天気は晴れです
もう一度コンテナを停止して破棄します.
% docker compose down ⏎
[+] Running 2/2
✔ Container mysql9 Removed 1.6s
✔ Network mysql01_default Removed 0.2s
%
ビルドキャッシュを削除する
ボリュームも含めたストレージの使用量を確認することができます.なお,現時点では大きくありませんが,ビルドを何度も実行すると Build Cache
が多くのストレージを消費することもあります.このキャッシュのおかげで再ビルドが高速になりますが,ストレージの消費超が気になる場合は削除することができます.
% docker system df ⏎
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 5 0 2.144GB 2.144GB (100%)
Containers 0 0 0B 0B
Local Volumes 1 0 205MB 205MB (100%)
Build Cache 24 0 62.83MB 62.83MB
%
ビルドキャッシュを削除します.
% docker builder prune ⏎ WARNING! This will remove all dangling build cache. Are you sure you want to continue? [y/N] y ⏎
ビルドキャシュの削除が確認できました.
% docker system df ⏎
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 5 0 2.144GB 2.144GB (100%)
Containers 0 0 0B 0B
Local Volumes 1 0 205MB 205MB (100%)
Build Cache 24 0 0B 0B
%