在預設的情況下,Compose會為我們的 app 建立一個 <app名>_default
的 network,在services 下的所有容器皆可使用這個 network 互相溝通(reachable),並可以在容器下以主機名稱標示彼此(discoverable by them at a hostname identical to the container name)
假設有個 app 叫做 myapp
,docker-compose.yml內容如下:
version: "3.9"
services:
web:
build: .
ports:
- "8000:8000"
db:
image: postgres
ports:
- "8001:5432"
當我們使用docker compose up
時:
1. 一個叫 myapp_default
的網路會被建立
2. 一個叫 web
的 container 被建立,並以 web
這個主機名稱加入myapp_default
網路
3. 一個叫 db
的 container 被建立,並以 db
這個主機名稱加入myapp_default
網路
只要在 myapp_default
網路下,使用 web
或 db
這兩個主機名稱,便可取得他們的 ip(虛擬 ip),例如 web
就可以利用 postgres://db:5432
來連接到DB的服務
注意ip的部分,格式為HOST_PORT:CONTAINER_PORT
,在容器之間可以使用 CONTAINER_PORT
來連接,若需從外部連線(如從HOST連入容器),便必須要使用 HOST_PORT
除了使用default network之外,我們也可以在top-level新增一個networks區塊來自定服務的網路環境,例如更複雜的拓墣環境、指定network drivers等等。
每個 service 可以在他們的networks區塊中去配置要連線到的網路環境,而此網路環境會被 top-level 的 networks 定義,我們可以藉由配置不同的網路環境,讓service之間達到隔離的效果,以下有一個範例:
version: "3.9"
services:
proxy:
build: ./proxy
networks:
- frontend
app:
build: ./app
networks:
- frontend
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
# Use a custom driver
driver: custom-driver-1
backend:
# Use a custom driver which takes special options
driver: custom-driver-2
driver_opts:
foo: "1"
bar: "2"
我們可以看到在top-level的networks中,有兩個網路環境 frontend
和 backend
被定義,而在service區塊中proxy
和db
,分別只有frontend
和backend
,因此proxy
和db
在網路上就被分隔出來,僅有app可以同時和他們溝通
若想要把 app container 加入一個已存在的網路(或是不想建立[projectname]_default
的網路),我們可以加入一個external和name的list來讓app 加入指定的網路:
services:
# ...
networks:
default:
name: my-pre-existing-network
external: true