docker compose 配置文件指令詳解
上一節我們快速體驗了 Docker Compose,本節我們來學習如何編寫和使用 Docker Compose。
Docker Compose 的配置文件是一個基于 YAML 格式的文件。與 Dockerfile 采用 Dockerfile 作為默認文件名一樣,Docker Compose 的配置文件也有一個缺省的文件名,就是 docker-compose.yml。
Docker Compose 將所管理的容器分為三層,分別是工程(project)、服務(service)、容器(container),Docker Compose 定義了一個工程,一個工程包含多個服務,每個服務中定義了容器運行的鏡像、參數、依賴,一個服務可包括多個容器實例。
1. 梳理工程中各個服務和容器的關系
Docker Compose配置文件有多個層級,直接學習指令不便于理解,通過一個熟悉的例子來掌握它是個更好的辦法。
以先前的配置文件為例,從Docker Compose的角度看,多個互相關聯的容器構成了一個工程。這個工程中包含應用服務app和數據緩存服務cache。
-
緩存服務cache包含redis容器,它提供給工程中的其他容器redis服務。
-
應用服務app中包含我們自定義的Dockerfile構建生成的容器,容器的運行依賴redis服務。
Tips: 需要注意的是,先前借用宿主機網絡直接進行容器通信過于簡單粗暴。我們只需要對外暴露flask 應用的 5000 端口就足夠了,因此在 Docker Compose 容器編排中,需要維護額外的 Docker 網絡,來處理這個工程中各容器通信。
2. 詳解配置指令
這里是上一節中使用的 Docker Compose 配置文件,它包含許多內容,從每個容器的各個細節控制,到網絡、數據卷等的定義。
本節我們加入了注釋來快速了解它。
# 指定配置文件的版本號
version: "3.8"
# 服務
services:
# 服務名稱cache
cache:
# 標明構建的鏡像
image: redis:6.0.5
# 生成的容器名稱
container_name: my_redis
# 指定網絡
networks:
- mynetwork
# 設定掛載
volumes:
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
# 容器啟動后執行命令
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# 服務名稱app
app:
# 構建鏡像
build:
# 指定上下文
context: .
# 指定構建腳本
dockerfile: ./Dockerfile-multi-stage
# 生成的容器名稱
container_name: my_hello
# 指定網絡
networks:
- mynetwork
# 配置環境變量
environment:
- REDIS_HOST=my_redis
# 指名容器依賴關系
depends_on:
- cache
# 宿主機與容器端口映射
ports:
- "5000:5000"
# 網絡配置,與services在同一層級,注意書寫格式對齊
networks:
# 標識自定義的網絡,對應容器中指定的網絡的名稱
mynetwork:
# 在容器網路中展示的名稱
name: my_network
# 網絡驅動類型
driver: bridge
基本的結構示意圖如下:
接下來,我們認識一下這個例子中出現的一些常用指令:
2.1 version
版本號標識我們定義的 docker-compose.yml 文件內容所采用的版本,目前 Docker Compose 的配置文件已經迭代至了第三版,其所支持的功能也越來越豐富,建議使用最新的版本來定義。對照表如下:
Compose 配置文件版本 | Docker 版本 |
---|---|
3.8 | 19.03.0+ |
3.7 | 18.06.0+ |
3.6 | 18.02.0+ |
3.5 | 17.12.0+ |
3.4 | 17.09.0+ |
3.3 | 17.06.0+ |
3.2 | 17.04.0+ |
3.1 | 1.13.1+ |
3.0 | 1.13.0+ |
2.4 | 17.12.0+ |
2.3 | 17.06.0+ |
2.2 | 1.13.0+ |
2.1 | 1.12.0+ |
2.0 | 1.10.0+ |
1.0 | 1.9.1.+ |
2.2 service
在 Docker Compose 把 service 作為配置的最小單元。使用時,我們首先要為每個服務定義一個名稱,用以區別不同的服務。在這個例子里,cache、redis 就是服務的名稱。雖然看上去每個 service 里的配置內容就像是在配置單個容器,但其實 service 代表的是一個應用集群的配置,這個部分我們會在后續的實戰環節接觸到。
2.3 image
類似于Dockerfile中的FROM
指令。需要注意,一定要注明鏡像的具體版本號,不要使用latest版本(不標明版本即為latest),不同的執行時間,latest指代的鏡像會發生改變。準確執行唯一指定的容器才能使得整個工程正確運行。
2.4 build
build另一種指定鏡像的方式,通過 build 這個配置我們能夠直接采用 Dockerfile 來構建鏡像,定義構建的環境目錄。
如果我們通過這種方式指定鏡像,那么 Docker Compose 先會幫助我們執行鏡像的構建,之后再通過這個鏡像啟動容器。Docker Compose 我們能夠指定更多的鏡像構建參數,例如 Dockerfile 的文件名,構建上下文,構建參數等等。
此外,與image
指令類似,我們希望Dockerfile的構建也是唯一可靠的,因此之前Dockerfile的寫法也是不夠穩定的,請讀者自行在Dockerfile中的鏡像和依賴上標明合適的版本號。
2.5 container_name
指定容器名稱,如果不指定,會以<項目名稱><服務名稱><序號>。其中項目名稱默認是當前工作目錄的名字。
2.6 command
例如上面的配置里,我們希望修改 Redis 的啟動命令,加入配置文件以便對 Redis 服務進行配置,那么我們可以直接通過 command 配置來修改。command
會覆蓋鏡像中的CMD
指令。
2.7 depends_on
在上面的例子里,我們的 app 依賴 cache,使用 depends_on 這個配置項,列出這個服務所有依賴的其他服務即可。在 Docker Compose 為我們啟動項目的時候,會檢查所有依賴,按照依賴指定的啟動順序來依次啟動容器。
2.8 volumes
在 Docker Compose 里定義文件掛載的方式與 Docker里也并沒有太多的區別,使用 volumes 配置可以像 docker 的 -v
選項一樣來指定外部掛載和數據卷掛載。在這個例子中,我們將redis的配置文件掛載到容器中。
2.9 ports
ports 這個配置項,它是用來定義端口映射的。我們可以利用它進行宿主機與容器端口的映射,這個配置與 docker 中 -p
選項的使用方法是近似的。
2.10 environment:
設置環境變量, 類似于 Dockerfile 的 ENV
。
2.11 networks
網絡也是容器間互相訪問的橋梁,網絡的配置對于多個容器組成的應用系統來說也是非常重要的。在 Docker Compose 里,我們可以為整個應用系統設置一個或多個網絡。
要使用網絡,我們必須先聲明網絡。聲明網絡的配置同樣獨立于 services 存在,是位于根配置下的 networks 配置。在上面的例子里,我們聲明了網絡mynetwork,在服務的配置中,直接使用networks指定mynetwork即可。
2.12 name
networks下的name的作用類似于 container_name
指令,在這個例子中,mynetwork 創建的 docker 網絡被命名為 my_network, 使用命令 docker network ls
可以查看到它。
3.小結
本節帶領大家認識了配置文件的基本結構和常用指令,這些指令是我們構建 Docker Compose 工程中最最常用的,是指令當中的“骨干成員”,請務必要掌握它們的基本用法。