はじめに
MySQLコンテナ起動時に発生するポートの競合の原因と対応について調べた内容をまとめます。
「ポート」とは
- データの送受信の窓口となる仕組み
- ポートを識別する番号を「ポート番号」という
「3306番ポート」の用途
- MySQLやMariaDBなどが外部からの接続を待ち受けるポートの番号(デフォルトの設定)
MySQLコンテナ起動時のポートの競合
- docker_compose.yml
- ホストの3306番ポートをコンテナの3306番ポートにマッピングしている
docker_compose.yml
services:
db:
image: mysql:8.0.42
ports:
- "3306:3306"
(省略)
- ホストの3306番ポートが他のプロセスで使用されている状況でMySQLコンテナを起動すると競合が発生して起動が失敗する
$ docker compose up -d
[+] Running 1/1
✔ Container app-db-1 Created 0.0s
Error response from daemon: driver failed programming external connectivity on endpoint app-db-1 (XXXXX): Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use
対応策①
3306番ポートを使用しているプロセスを特定し、終了させる
- 3306番ポートを使用しているプロセスを特定する
-
lsof
コマンド: 「list open files」の意味で、オープン中のファイルやそのファイルをオープンしているプロセスのリストを出力するコマンド
-
$ sudo lsof -i:3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 2011 mysql 48u IPv6 41956 0t0 TCP *:mysql (LISTEN)
- 3306番ポートを使用しているプロセスを終了させる
$ sudo kill [PID] # 上記の場合のPIDは2011
- MySQLコンテナを起動できるようになる
$ docker compose up -d
[+] Running 1/1
✔ Container app-db-1 Started
- 起動後の状態で3306番ポートを使用しているポートを確認すると下記のように変更されていることが確認できる
$ sudo lsof -i:3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
docker-pr 10731 root 4u IPv4 142710 0t0 TCP *:mysql (LISTEN)
docker-pr 10737 root 4u IPv6 144160 0t0 TCP *:mysql (LISTEN)
- ホストの3306番ポートをMySQLコンテナの3306番ポートにマッピングできていることが確認できる
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd4813c10f35 mysql:8.0.42 "docker-entrypoint.s…" 13 seconds ago Up 2 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp app-db-1
対応策②
ホストのポート番号を3306番以外に変更する
- docker_compose.yml
- ホストのポート番号を3306以外(例では3307)に変更する
services:
db:
image: mysql:8.0.42
ports:
- - "3306:3306"
+ - "3307:3306"
(省略)
- 競合は発生せず起動できるようになる
$ docker compose up -d
[+] Running 1/1
✔ Container app-db-1 Started
- ホストの3307番ポートをMySQLコンテナの3306番ポートにマッピングできていることが確認できる
$ sudo lsof -i:3307
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
docker-pr 11423 root 4u IPv4 145784 0t0 TCP *:opsession-prxy (LISTEN)
docker-pr 11429 root 4u IPv6 148040 0t0 TCP *:opsession-prxy (LISTEN)
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
XXXXXXXXXXXX mysql:8.0.42 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp app-db-1