Docker Compose 使用 YAML 文件來定義多服務的應用。YAML 是 JSON 的一個子集,因此也可以使用 JSON。
Docker Compose 默認使用文件名 docker-compose.yml。當然,也可以使用 -f 參數指定具體文件。
如下是一個簡單的 Compose 文件的示例,它定義了一個包含兩個服務(web-fe 和 redis)的小型 Flask 應用。
這是一個能夠對訪問者進行計數并將其保存到 Redis 的簡單的 Web 服務。
version: "3.5"
services:
web-fe:
build: .
command: python app.py
ports:
- target: 5000
published: 5000
networks:
- counter-net
volumes:
- type: volume
source: counter-vol
target: /code
redis:
image: "redis:alpine"
networks:
counter-net:
networks:
counter-net:
volumes:
counter-vol:
在深入研究之前粗略觀察文件的基本結構,首先可以注意到,它包含 4 個一級 key:version、services、networks、volumes。
version 是必須指定的,而且總是位于文件的第一行。它定義了 Compose 文件格式(主要是 API)的版本。
注意,version 并非定義 Docker Compose 或 Docker 引擎的版本號。
示例中 Compose 文件將使用版本 3 及以上的版本。
services 用于定義不同的應用服務。上邊的例子定義了兩個服務:一個名為 web-fe 的 Web 前端服務以及一個名為 redis 的內存數據庫服務。
Docker Compose 會將每個服務部署在各自的容器中。
networks 用于指引 Docker 創建新的網絡。默認情況下,Docker Compose 會創建 bridge 網絡。
這是一種單主機網絡,只能夠實現同一主機上容器的連接。當然,也可以使用 driver 屬性來指定不同的網絡類型。
下面的代碼可以用來創建一個名為 over-net 的 Overlay 網絡,允許獨立的容器(standalone container)連接(attachable)到該網絡上。
networks:
over-net:
driver: overlay
attachable: true
volumes 用于指引 Docker 來創建新的卷。
上面例子中的 Compose 文件使用的是 v3.5 版本的格式,定義了兩個服務,一個名為 counter-net 的網絡和一個名為 counter-vol 的卷。
更多的信息在 services 中,下面仔細分析一下。
Compose 文件中的 services 部分定義了兩個二級 key:web-fe 和 redis。
它們各自定義了一個應用程序服務。需要明確的是,Docker Compose 會將每個服務部署為一個容器,并且會使用 key 作為容器名字的一部分。
本例中定義了兩個 key:web-fe 和 redis。因此 Docker Compose 會部署兩個容器,一個容器的名字中會包含 web-fe,而另一個會包含 redis。
web-fe 的服務定義中,包含如下指令。
⒈build
指定 Docker 基于當前目錄(.)下 Dockerfile 中定義的指令來構建一個新鏡像。該鏡像會被用于啟動該服務的容器。
⒉command
python app.py 指定 Docker 在容器中執行名為 app.py 的 Python 腳本作為主程序。
因此鏡像中必須包含 app.py 文件以及 Python,這一點在 Dockerfile 中可以得到滿足。
⒊ ports
指定 Docker 將容器內(-target)的 5000 端口映射到主機(published)的 5000 端口。
這意味著發送到 Docker 主機 5000 端口的流量會被轉發到容器的 5000 端口。容器中的應用監聽端口 5000。
⒋ networks
使得 Docker 可以將服務連接到指定的網絡上。這個網絡應該是已經存在的,或者是在 networks 一級 key 中定義的網絡。
對于 Overlay 網絡來說,它還需要定義一個 attachable 標志,這樣獨立的容器才可以連接上它(這時 Docker Compose 會部署獨立的容器而不是 Docker 服務)。
⒌ volumes
指定 Docker 將 counter-vol 卷(source:)掛載到容器內的 /code(target:)。
counter-vol 卷應該是已存在的,或者是在文件下方的 volumes 一級 key 中定義的。
綜上,Docker Compose 會調用 Docker 來為 web-fe 服務部署一個獨立的容器。該容器基于與 Compose 文件位于同一目錄下的 Dockerfile 構建的鏡像。
基于該鏡像啟動的容器會運行 app.py 作為其主程序,將 5000 端口暴露給宿主機,連接到 counter-net 網絡上,并掛載一個卷到/code。
從技術上講,本例并不需要配置 command: python app.py。因為鏡像的 Dockerfile 已經將 python app.py 定義為了默認的啟動程序。
但是,本例主要是為了展示其如何執行,因此也可用于覆蓋 Dockerfile 中配置的 CMD 指令。
redis 服務的定義相對比較簡單。
⒍ image
redis:alpine 使得 Docker 可以基于 redis:alpine 鏡像啟動一個獨立的名為 redis 的容器。
這個鏡像會被從 Docker Hub 上拉取下來。
⒎ networks
配置 redis 容器連接到 counter-net 網絡。
由于兩個服務都連接到 counter-net 網絡,因此它們可以通過名稱解析到對方的地址。了解這一點很重要,本例中上層應用被配置為通過名稱與 Redis 服務通信。