神戸学院大学 経営学部 林坂ゼミ

Docker 入門トップページ

« 戻る 次へ »

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 というデータベースにはアクセスできるものの,mysqlsys というデータベースには 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 ディレクトリに移動します.なお,lscd といったコマンドに関する説明はここを参照してください.

% 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 にある mysql9docker-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
%