0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.js + Docker + Mac でポート衝突する地獄と解決法

Posted at

Next.js + Docker + Mac でポート衝突する地獄と解決法

はじめに

Mac で Next.js を Docker 上で動かしていると、
ある日突然 Error: ports are not available の恐怖に襲われることがあります。
再起動しても直らず、他のコンテナを落としても解決しない——まさに“ポート地獄”。
この記事では、この現象の原因と解決方法をシンプルに整理します。


1. 発生するエラーメッセージ

Error response from daemon: ports are not available: 
exposing port TCP 127.0.16.31:9000 -> 127.0.0.1:0: listen tcp4 ...: bind: can't assign requested address

または:

Bind for 0.0.0.0:3000 failed: port is already allocated

2. 原因の正体

このエラーは、Docker ネットワークが macOS の lo0 インターフェース(ループバック)に正しく紐付けられないことが原因です。
Apple Silicon 環境(M1/M2 Mac)では 127.0.16.x 系の仮想アドレスを使うため、
これが正常に解放されないとポート衝突が起きます。

主な原因まとめ

  • 以前のコンテナが「ゴースト状態」で残っている
  • Docker が lo0 に追加したエイリアスが削除されていない
  • docker-compose.yml 内で固定IPを指定していて競合している
  • macOS の Firewall / VPN がループバック通信をブロックしている

3. まず確認するべきこと

(1) ポートがすでに使われていないか確認

lsof -i :3000

もし出力があれば、そのプロセスを終了。

kill -9 <PID>

(2) 使っているDockerネットワークを確認

docker network ls
docker network inspect <network_name>

"IPAM": { "Config": [ { "Subnet": "172.31.0.0/16" } ] } のような部分に注目。
複数のネットワークで同じサブネットを使っていると衝突します。


4. 即効性のある解決法

✅ 1. コンテナとネットワークを一度全部削除

docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
docker network prune -f
docker volume prune -f

→ これで大抵のポート衝突は解消。


✅ 2. lo0 にエイリアスを再設定(Mac専用)

Apple Siliconでは、127.0.16.x がDockerコンテナの仮想アドレスになります。
これを再設定するスクリプトを /tmp/add-lo0-aliases.sh に作成。

#!/bin/bash
for i in $(seq 1 20); do
  sudo ifconfig lo0 alias 127.0.16.$i up
done

実行:

sudo bash /tmp/add-lo0-aliases.sh

✅ 3. docker-compose.yml の固定IP設定を削除

services:
  app:
    ports:
      - "3000:3000"
    networks:
      app_net:
        ipv4_address: 172.31.0.5  # ← これを削除

固定IPを削除すると、Docker が自動的に安全なアドレスを割り当てます。


5. 恒久的な対策

💡 1. Mac再起動時に自動でlo0エイリアスを再設定

/usr/local/bin/docker-up-fix.sh に次のスクリプトを登録:

#!/bin/bash
for i in $(seq 1 20); do
  if ! ifconfig lo0 | grep -q "127.0.16.$i"; then
    sudo ifconfig lo0 alias 127.0.16.$i up
  fi
done

ログイン時に自動実行するように launchctl へ登録しておくと安心です。


💡 2. .env でポートを可変にしておく

複数プロジェクトで同じポートを使うと衝突します。
.envにポート番号を変数化して、compose内で参照するのがおすすめ。

ports:
  - "${APP_PORT:-3000}:3000"

💡 3. Docker Desktop を定期的に再起動

macOS のネットワークキャッシュは永続化されるため、
定期的に Docker Desktop を再起動してキャッシュをクリアするのが効果的。


6. それでも直らないとき

  • VPNをOFFにする(一部VPNが127系通信を奪う)
  • RosettaでDockerを動かす(一部のamd64イメージがarm64と競合)
  • Docker Desktopをリセット(設定 → Troubleshoot → Reset to factory defaults)

まとめ

Next.js と Docker は最高の組み合わせですが、Mac環境ではネットワーク周りに独特の罠があります。
焦らず「lo0」「固定IP」「ポート競合」の3点をチェックすれば、ほとんどのケースで復旧可能です。
この“地獄”を一度経験すれば、もう怖いものはありません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?