環境
- MacBook Pro M3
- macOS Sonoma
- Rancher Desktop 1.14.0
方法
ローカル環境でDockerコンテナ上にDBを構築する方法を説明します。DBMSはMySQLを使用します。
構築時にはDBに初期データを投入します。また、コンテナ上のDBに接続して、初期データが登録できているか確認します。
最後に、作成したコンテナとボリューム、自動で作成されたデフォルトネットワークを削除します。
コンテナ上にDBを構築する方法
以下の各ファイルをコピペして用意してください。
explain-db
├── docker-compose.yaml # コンテナの設定を記載します。
└── initdb.d
├── 1-schema.sql # DBのテーブル定義を記載します。
└── 2-data.sql # 初期データをDBに投入するSQL文を記載します。
services:
db:
container_name: test-container
image: mysql:8
volumes:
- ./initdb.d:/docker-entrypoint-initdb.d
- test-database-volume:/var/lib/mysql
environment:
MYSQL_DATABASE: test-database
MYSQL_ROOT_PASSWORD: root
TZ: Asia/Tokyo
ports:
- "3306:3306"
volumes:
test-database-volume:
USE test-database;
CREATE TABLE organization_t (
organization_id MEDIUMINT NOT NULL AUTO_INCREMENT,
organization_name VARCHAR(64) NOT NULL,
register_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (organization_id)
);
INSERT INTO organization_t (organization_name)
VALUES
('Google'),
('Microsoft');
以下のコマンドを実行して、コンテナを起動します。
$ docker compose up -d
[+] Running 3/3
✔ Network explain-db_default Created 0.1s
✔ Volume "explain-db_test-database-volume" Created 0.0s
✔ Container test-container Started 0.3s
-d
(または--detach
)オプションはバックグラウンドでコンテナを起動します。
以下のコマンドを実行すると、起動中のコンテナの一覧を確認できます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
68e5a2024cae mysql:8 "docker-entrypoint.s…" 5 seconds ago Up 3 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp test-container
以下のコマンドを実行すると、ボリュームの一覧を確認できます。
$ docker volume ls
DRIVER VOLUME NAME
local explain-db_test-database-volume
これでDBの構築は完了です。
次にコンテナ上のDBに接続してSQL文を実行し、初期データが登録できているか確認します。
コンテナ上のDBに接続してSQL文を実行する方法
以下のコマンドを実行して、コンテナ内にbashシェルを起動し、現在のターミナルウィンドウに入力されるコマンドが、コンテナ内のbashシェルに渡されて実行されるようにします。
$ docker exec -it test-container bash
以下のコマンドを実行して、DBに接続します。
bash-5.1# mysql -u root -proot
以下の2つのコマンドを実行して、初期データが登録できているか確認します。
mysql> use test-database;
Database changed
mysql> select * from organization_t;
+-----------------+-------------------+---------------------+---------------------+
| organization_id | organization_name | register_time | update_time |
+-----------------+-------------------+---------------------+---------------------+
| 1 | Google | 2024-07-13 11:43:44 | 2024-07-13 11:43:44 |
| 2 | Microsoft | 2024-07-13 11:43:44 | 2024-07-13 11:43:44 |
+-----------------+-------------------+---------------------+---------------------+
2 rows in set (0.00 sec)
コンテナとボリュームを削除する方法
以下のコマンドを実行して、作成したコンテナとボリューム、自動で作成されたデフォルトネットワークを削除します。
$ docker compose down -v
[+] Running 3/3
✔ Container test-container Removed 1.9s
✔ Volume explain-db_test-database-volume Removed 0.0s
✔ Network explain-db_default Removed 0.5s
-v
(または--volumes
)オプションはボリュームを一緒に削除します。
以下のコマンドを実行して、起動中あるいは停止中のコンテナが存在しないことを確認します。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
-a
(または--all
)オプションは停止中のコンテナも含めて全てのコンテナを表示します。
以下のコマンドを実行して、ボリュームが存在しないことを確認します。
$ docker volume ls
DRIVER VOLUME NAME
トラブルシュート
エラーが出力される場合や記述通りの実行結果が得られない場合は以下を参考にしてください。
「port is already allocated
」というエラー文が表示される場合
$ docker compose up -d
Error response from daemon: driver failed programming external connectivity on endpoint test-container (f6205f9951d14670ecf150984863cbacda7d598a39e5d95ecdd33557eedfd149): Bind for 0.0.0.0:3306 failed: port is already allocated
docker-compose.yaml
でホストマシンの3306
ポートを指定しましたが、既にそのポートを他のプロセスが占有している(つまり、そのポートで他のプログラムが実行されている)際に起きるエラーです。
このエラーは以下のどちらかを行うと解決できます。
解決方法(1) docker-compose.yaml
で指定したポート番号を変更する
ports
の:
の左側の番号を別の番号に変更します。
- 0番から1023番は使用しないでください
- 変更後のポート番号も、また別のプロセスと競合する可能性があります
ports:
- "3330:3306" # {ホストマシンのポート}:{コンテナのポート}の形式
解決方法(2) ホストマシンの3306
ポートを占有するプロセスを強制終了させる
まず、以下のコマンドを実行して、3306
ポートを占有しているプロセスを調べます。
$ lsof -i :3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ssh 2063 xxxxxx-xxx 35u IPv4 xxxxxxxxxxxxxxxxxx 0t0 TCP *:mysql (LISTEN)
次に、上記で調べたプロセスのPIDを指定して、プロセスを強制終了させます。
kill -9 2063