Featured image of post 避免 Docker 將 Port 暴露至所有網路介面

避免 Docker 將 Port 暴露至所有網路介面

Docker 預設會將 port 綁定到 0.0.0.0,也就是所有網路介面。如果 guest host 同時掛多網卡/多網段,這個行為很容易在無意間把服務曝露到不該曝露的地方。

收斂 bind 範圍有兩個切入點:在 Docker Daemon 層設定預設 IP,或在 docker-compose 層直接指定。

方法一:修改 Docker Daemon 預設 Bind IP

編輯(或建立)/etc/docker/daemon.json,加入 ip 欄位:

1
2
3
{
    "ip": "192.168.0.10"
}

存檔後重啟 Docker 服務:

1
sudo systemctl restart docker

重啟後,所有 container 的 port mapping 若未明確指定 bind IP,就會預設綁定到 192.168.0.10,而非 0.0.0.0

已存在的 container 不受影響,需要重新佈署才會套用新的預設值。

方法二:在 docker-compose 直接指定 Bind IP

不想動 daemon 設定,或需要個別服務綁定不同 IP 時,直接在 ports 欄位指定:

1
2
3
ports:
  - "192.168.2.199:443:443"
  - "192.168.2.199:80:80"

格式為 HOST_IP:HOST_PORT:CONTAINER_PORT。明確寫出 IP,Docker 就不會自動綁定到其他介面。

批次更新現有的 docker-compose.yml

如果有多個 compose 檔要一次處理,可以用這段 script 自動加上 bind IP:

1
2
echo "BIND_IP=$( hostname -I | awk '{ print $1 }' )" >> .env && \
sed -i -E 's/(\-\s)"*([0-9]+\:[0-9]+(\/[a-z]+)*)"*+/\1${BIND_IP}:\2/g' docker-compose.yml

這段指令做兩件事:

  1. 取得主機的第一張網卡 IP,以 BIND_IP 為名寫入 .env
  2. sed 將 compose 檔內所有 port mapping 加上 ${BIND_IP}: 前綴

docker-compose 會自動讀取同目錄下的 .env,所以 ${BIND_IP} 在啟動時會被展開成實際 IP。

如需還原則執行:

1
sed -i 's/${BIND_IP}://g' docker-compose.yml
Licensed under CC BY-NC-SA 3.0 TW
最後更新 2026-05-07
comments powered by Disqus