Dockerのport is already allocated・address already in useの原因と対処
port is already allocatedやbind: address already in useでコンテナが起動できない場合に、ホスト側の待ち受けとDockerのポート公開設定を分けて確認する障害ガイドです。
この記事の目的
競合しているホストポート・IP・プロセスを特定し、既存サービスを停止せず変更案を判断します。
まず確認すること
docker context show→docker ps --format→daemonホスト上でss -lntpでDockerとホスト側の利用状況を調べます。
web01・app-data・ポート番号などは説明用です。Docker context・対象コンテナ・データ保存先を照合してください。関連ガイド
Docker基本操作
コンテナの状態確認、起動・停止、接続先の基本操作へ戻ります。
ガイドへ →DockerDocker Compose設定
compose.yamlの変数、ポート、永続化、反映前チェックを確認します。
ガイドへ →DockerDockerコンテナ起動失敗
Exited・Restarting・OOMKilledなどの終了原因を切り分けます。
ガイドへ →1. このエラーはどこで起きるか
DockerがコンテナのポートをホストIP・ホストポートに公開しようとした際、競合やバインド制約で失敗することがあります。たとえば-p 8080:80はホスト側8080番からコンテナ側80番へ転送する指定です。調査対象は原則としてホスト側8080番です。
address already in useは、同じコンテナ内部での二重起動等が原因の場合もあります。その場合はコンテナ起動失敗の記事でアプリログを確認します。2. 読み取りコマンドだけで競合を調査
リモートDockerではCLI端末上ではなくdaemonホスト上でssを実行します。ssで競合元が表示されない場合も、Dockerがポート予約を持っていることがあります。また、IPv4/IPv6、指定したbindアドレス、ホストネットワークの設定によって結果の解釈が変わります。
3. コンテナが占有している場合
Compose設定が複数ファイルに分かれている場合は、実際に起動するディレクトリと-f指定、プロジェクト名を合わせて確認します。docker compose configは環境変数を展開した内容が出るため、共有時は秘匿情報を伏せてください。
4. プロトコル・公開IPの確認漏れを防ぐ
ssで待ち受けが見えなくても、Docker側の公開設定や、操作先が別のDocker contextである可能性を排除できません。8080:80は通常TCPを意味しますが、UDPを利用する場合は指定と確認コマンドの双方でプロトコルをそろえます。IPv6や特定IPのみの待ち受けを、IPv4全体の競合と混同しないでください。
ポート変更後は、対象サービスの待ち受けだけでなく、既存クライアント、リバースプロキシ、監視設定、外部公開の必要性まで確認します。既存プロセスのkillは自動対処に含めません。
5. 解消の選択肢を比較する
| 対応案 | 効果 | 本番確認 |
|---|---|---|
| ホストポートを変更 | 既存利用者への干渉を避けられる場合がある | LB・Firewall・監視・接続先変更が必要 |
| 既存サービスを停止 | ポートが解放される可能性 | 既存業務の停止影響・依存関係の確認が必要 |
| 別IPへ限定して公開 | 同じポートを別IPで利用できる場合がある | NIC・bind・Firewall・到達性を検証 |
| 不要なコンテナの整理 | 意図せず残っていた公開設定を解消 | 本当に不要か、データが残るかを確認 |
検証用の公開例は127.0.0.1:8081:80のようにlocalhostへ限定できますが、利用者が外部から接続する要件には適しません。業務要件に応じて設計します。
127.0.0.1指定だけで完全に隔離されると判断せず、Engineのバージョン・ホストのネットワーク・Firewallを確認してください。Docker公式の注意事項を参照。6. bindできても外部接続できない場合
ポート競合エラーがなくても、通信できるとは限りません。待ち受けアドレス・Firewall・DockerのNAT/フィルター・リバースプロキシ・コンテナアプリのポートを区別して調べます。
Linux側の到達性はネットワーク疎通・接続障害ガイドを参照。Dockerはホストのファイアウォールルールへ影響するため、公開ポートの設定変更にはセキュリティ監査が必要です。
7. 修正後の確認・再発防止
起動成功だけでなく、外部から到達可能であるべき範囲と実際の公開範囲が一致しているかを確認します。ポート番号の割り当て台帳を管理し、変更前の使用状況を記録してください。
8. ポート競合の原因別に設定を直す
同じ8080番の競合でも、ホスト側プロセスが占有している場合と別コンテナが公開している場合では操作対象が異なります。以下は説明用の出力例であり、実機実測ではありません。
| 確認した結果 | 安全な対応の選び方 |
|---|---|
| ホストのnginx等が8080を使用 | 業務サービスなら停止しない。新しいコンテナのホスト側公開ポートを変更できるか検討 |
| 既存Dockerコンテナが8080を公開 | 所有プロジェクト・サービスへの接続を確認。不要と確定していないコンテナを削除しない |
| TCPのssに表示されないがbindに失敗 | IPv6/UDP、別context、公開IP、daemonの状態・ログを調査。TCPだけで空きと判断しない |
| bindできるが外部から接続不能 | 競合とは別問題。公開先IP、アプリlisten、Firewall・Proxyを確認し、ネットワーク疎通ガイドへ |
検証用nginxのComposeをlocalhostの8081へ変更する設定例です。実務上の公開範囲はセキュリティ要件に合わせて判断してください。
9. ポート変更後の成功・失敗判定
curlが成功しても、意図せず外部へ公開されていればセキュリティ上は不合格です。サービスの正常性と公開範囲は分けて検証します。
| 確認結果 | 判定と次の行動 |
|---|---|
| localhostのcurl成功、Dockerの公開先も想定どおり | ローカル疎通は成功候補。外部非公開が要件なら別ホストから到達しないことも確認 |
0.0.0.0:8081等の広い公開になっている | 設計に反する場合は不合格。公開IP、Firewall、Docker Engineのバージョンを確認して修正 |
| 新ポートの疎通は成功したが旧利用者は失敗 | LB・Proxy・クライアント接続先の切替が未完了。影響先を調査し、必要なら旧設定へ切り戻す |
| コンテナ自体が起動しない | 起動失敗の診断へ。ポート変更だけで解決したと判断しない |