容器之間要用容器名稱連線而不是 localhost
App 容器要連 DB 容器,host 填
localhost是錯的——初學第二名的卡關點。每個容器有自己的 network namespace,App 容器裡的localhost指的是「App 容器自己」,所以只會拿到ECONNREFUSED。
正確做法
docker network create app-net # 1. 建自訂網路
docker run -d --name postgres --network app-net \
-e POSTGRES_PASSWORD=dev123 postgres:16-alpine # 2. DB 加入
docker run -d --name api --network app-net -p 3000:3000 \
-e DB_HOST=postgres -e DB_PORT=5432 my-app:1.0 # 3. App 加入,host 填容器名稱三個重點
- 用自訂 network — 只有自訂 network 才有容器名稱的 DNS 解析,預設 bridge 沒有
- 連線位址填容器名稱(
postgres),不是 localhost、不是 IP(IP 會變) - port 填容器內部原始 port(5432),不是
-p映射到主機的那個——容器之間的通訊根本不經過主機,跟-p無關
安全紅利
-p 只在「從容器外面連進去」時才需要。所以正式環境常見做法是:只有對外的 API / nginx 容器開 -p,資料庫容器完全不開——資料庫從外網根本連不到。
除錯
docker exec -it api sh 後 ping postgres 或 nc -zv postgres 5432:ping 不到=不在同一個網路;ping 得到但連不上=對方服務還沒起來或 port 錯。
網路模式:bridge(預設,99% 用這個)/host(不隔離,-p 失效,Mac 支援有限)/none/overlay(跨主機叢集)。