關於 docker-compose 的安裝,關於 docker 的基本介紹,不在本文的指導範圍內。php
這篇文章基本上是 docker-compose YAML 文件格式的嚴格的英譯中。這麼作,緣起於昨天想起掃描一下 docker-compose 編排中怎麼使用 ${PWD}
的問題,結果中文沒有一點幫助,仍是官網最終解決了個人模糊之處。所以我以爲仍是應該作一篇比較嚴謹的譯文以及說明,來闡釋 docker-compose 編排的各項細節。html
如下,咱們主要是介紹 docker-compose 編排文件格式版本3 的各項細節。node
閱讀本文,你應該有 docker-compose 的基本認識,至少有基本的早期(版本2)編排格式的瞭解。mysql
譯文從屬於原文 docs.docker.com/compose/com…。linux
譯文 https://github.com/hedzr/docker-compose-file-format 自己以 MIT 方式(忽略 hedzr.github.io 站臺級許可申明,遵循 repo 自己的申明)分發。nginx
git
上一次我作了一箇舊的譯文:docker-compose 編排指南 (v3.7)。這是基於 v3.7 的。今次的譯文是對其的一個更新。不得不說,這種查漏補缺挺煩人的。github
版本3是自 docker-engine 1.13 推出以來 docker-compose 所支持的格式。這以前 docker 在 1.12 中推出了 swarm mode 來構建一個虛擬網絡中的虛擬計算資源,同時也大幅度改進了 docker 的網絡以及存儲的支持。golang
對於 docker-compose 編排格式與 docker-engine 之間的關係,下面這張表(摘自官網)有清晰的對照。web
Compose file format | Docker Engine release |
---|---|
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.+ |
這是一個版本3+的典型文件結構樣本:
version: "3.7" # 適用於 v3.8 沒問題
services:
redis:
image: redis:alpine
ports:
- "6379"
networks:
- frontend
deploy:
replicas: 2
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
db:
image: postgres:9.4
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
deploy:
placement:
constraints: [node.role == manager]
vote:
image: dockersamples/examplevotingapp_vote:before
ports:
- "5000:80"
networks:
- frontend
depends_on:
- redis
deploy:
replicas: 2
update_config:
parallelism: 2
restart_policy:
condition: on-failure
result:
image: dockersamples/examplevotingapp_result:before
ports:
- "5001:80"
networks:
- backend
depends_on:
- db
deploy:
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
worker:
image: dockersamples/examplevotingapp_worker
networks:
- frontend
- backend
deploy:
mode: replicated
replicas: 1
labels: [APP=VOTING]
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 120s
placement:
constraints: [node.role == manager]
visualizer:
image: dockersamples/visualizer:stable
ports:
- "8080:8080"
stop_grace_period: 1m30s
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]
networks:
frontend:
backend:
volumes:
db-data:
複製代碼
在這個樣本中,頂級結構由 version
,services
,networks
,volumes
等等標籤構成。這與版本2並無什麼翻天覆地的區別。
在 services
章節中,你能夠定義若干個服務,每一個服務一般運轉着一個容器,這些服務構成了一個總體的設施棧,又或是服務羣。
通常來講咱們會把一堆拉拉雜雜的東西,例如一堆微服務什麼的,編排成一個服務棧,讓他們總體對外服務,從而避免細節外露,也能夠增強架構設計彈性和對整個服務棧進行伸縮(而不是面對大批微服務去逐個處理)。
ENTRYPOINT
和 CMD
在 Dockerfile 中討論這三條命令:
首先,RUN
不考慮,其用途能夠被視做執行一條Shell指令。
CMD
和 ENTRYPOING
類似但實際上區別較大:CMD
指定默認命令及其命令行參數、或者命令行參數的結尾的部分,而且可以在啓動容器時被覆蓋(經過外部命令行指定的方式),ENTRYPOINT
指定該容器被運行時的啓動命令,能夠附帶命令行參數,這條命令在被實際執行時還會附加 CMD
所指定的內容做爲其命令行的結尾部分。
因此一個慣用法是:
ENTRYPOINT ["/bin/echo", "Hello"] CMD ["world"] 複製代碼
而後執行該容器的效果相似於:
$ docker run -it test-container
Hello world
$ docker run -it test-container David
Hello David
複製代碼
因此對於自定義容器來講,你的主要應用程序的路徑能夠被用做 ENTRYPOINT
而在 CMD
中提供默認參數:
ENTRYPOINT ["/usr/local/app/my-app"] CMD ["--help"] 複製代碼
這將會包裝你的 my-app 像一個外露的工具,默認時顯示其幫助屏,你能夠指定參數去運行 my-app:
$ docker run -it my-app-container
[... help screen here ...]
$ docker run -it my-app-container server run --foreground
[ 等同於執行 my-app server run --foreground ]
複製代碼
END
多遍構建被典型地用於CI/CD。
例如步驟0能夠被命名爲 builder
,負責從源碼編譯到目標文件,而步驟1則從步驟0中抽出目標文件用於部署打包,並生成最終的容器鏡像,隨後步驟0的中間層則被拋棄(僅指不被打包在結果容器中,實際上這些中間層在 Docker 的構建緩存中仍然是存在且能夠被重用的),這些中間層不會出如今最終容器鏡像中,從而有效地縮減了最終容器鏡像的尺寸,而這個結果也是從語義上、從邏輯上被自洽的。
FROM golang:1.7.3 AS builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
複製代碼
service
配置參考接下來會是一個參考手冊應有的章節結構,咱們按照字母順序列列舉出了服務編排的指令,例如
ports
,volumes
,cmd
,entry
等等。
Compose 文件是一個 YAML格式的文本文件,其中定義了 service、networks 以及 volumes。缺省時 docker-compose 使用和檢索 ./docker-compose.yml
文件並解釋之。
Tip: 你老是可使用
.yml
或.yaml
做爲該腳本文件的後綴,它們都會正確工做。
service (服務)的配置包含若干定義,它們指明瞭如何將一個容器運行爲服務,這些定義實際上會被傳遞給 docker run
做爲其命令行參數的一部分。一樣的道理,networks、volumes 等等的定義也採用一樣的原理去影響諸如 docker network create
,或者 docker volume create
等命令的實際運行。
你可使用在配置定義值中使用環境變量,它們有相似於 BASH 變量替代的語法,你能夠以 ${VARIABLE}
,請參閱 變量替換 小節的深刻探討。
接下來本章節中列舉全部有效的服務配置項。
build
該選項被用於構建。
build
能夠是一個指向構建上下文的路徑字符串,例如:
version: "3.8"
services:
webapp:
build: ./dir
複製代碼
也能夠是一個更詳細的定義。這包括了 context
項所指定的路徑,以及可選的 dockerfile
文件和構建參數 args
:
version: "3.8"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
複製代碼
若是你在指定了 build
的同時還指定了 image
,那麼構建的結果會被標記爲相應的名字,這就好像 docker build -t container-name:tag dir
作的那樣:
build: "./dir"
image: "company/webapp:v1.1.9"
複製代碼
對於 YAML 而言,避免歧義的安全作法是對字符串加上引號包圍。
上面這個例子,會找到 ./dir
文件夾中的構建上下文(默認是尋找到 Dockerfile
)並完成構建,最後將其標記爲 company/webapp
的名字,以及 v1.1.9
的 Tag。
NOTE 當用在docker stack部署場景時:
build
選項會被忽略。
context
能夠是一個包含 Dockerfile
的文件夾,也能夠是一個指向 git repository 的 URL。
若是指定了一個相對路徑,那麼這個路徑是相對於 docker-compose.yml
文件的。這個路徑也會被傳送給 Docker daemon 用於進行構建。
docker-compose 發動構建動做和標記構建結果(按照image
名字),在那以後按照對應的名字使用它。
build:
context: ./dir
複製代碼
dockerfile
能夠指定不一樣於默認名稱 Dockerfile
的其它文件名用於構建。注意同時必須指定路徑到 context
:
build:
context: .
dockerfile: Dockerfile-alternate
複製代碼
args
指定構建參數。一般是指用於構建時的參數(參見 Dockerfile 中的 ARG
)。
如下是一個簡要的概述:
首先,在 Dockerfile 指定參數:
ARG buildno
ARG gitcommithash
RUN echo "Build number: $buildno" RUN echo "Based on commit: $gitcommithash" 複製代碼
而後指定構建參數的實際值(傳入Map或者數組都是能夠的):
build:
context: .
args:
buildno: 1
gitcommithash: cdc3b19
複製代碼
或:
build:
context: .
args:
- buildno=1
- gitcommithash=cdc3b19
複製代碼
NOTE: 在 Dockerfile中,若是在
FROM
以前指定ARG
,那麼這個ARG
對於其後的FROM
閉包是無效的。多個
FROM
分別切割出了多個構建的閉包。想要
ARG
在每一個FROM
閉包中都有效,你須要在每一個閉包中都指定它。在 Understand how ARGS and FROM interact 中有更詳細的相關討論。
你能夠略過顯式指定構建參數。此時,該參數的實際值取決於構建時運行環境。
args:
- buildno
- gitcommithash
複製代碼
NOTE: YAML的布爾量(
true
,false
,yes
,no
,on
,off
)必須用引號包圍,以便 docker-compose正確處理。
cache_from
since v3.2
指定一個映像列表,用於緩存的解決。
build:
context: .
cache_from:
- alpine:latest
- corp/web_app:3.14
複製代碼
labels
since v3.3
向構建的映像中添加元數據標籤,能夠是一個數組或一個字典。
咱們推薦使用反向DNS標註性前綴以防止你的標籤和使用者的標籤相沖突:
build:
context: .
labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
# anothor example
build:
context: .
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
複製代碼
network
Since v3.4
設置在 RUN
構建過程當中要連接的網絡,該網絡也將被用於查詢和提取依賴的容器。
build:
context: .
network: host
build:
context: .
network: custom_network_1
複製代碼
設爲 none
則在構建時禁用網絡查詢和提取:
build:
context: .
network: none
複製代碼
shm_size
since v3.5
設置構建容器時的 /dev/shm
分區大小。整數格式按字節表示,但也可使用字符串格式(byte value):
build:
context: .
shm_size: '2gb'
build:
context: .
shm_size: 10000000
複製代碼
target
since v3.4
構建定義與 Dockerfile 中的特定的步驟(Stage),參閱 multi-stage build docs:
build:
context: .
target: prod
複製代碼
cap_add
, cap_drop
添加或者移除容器的 Linux 能力。完整的清單能夠參閱 man 7 capabilities
。
cap_add:
- ALL
cap_drop:
- NET_ADMIN
- SYS_ADMIN
複製代碼
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。
Linux 能力機制很大程度上是一種安全機制。具體含義、用途和引伸屬於 Linux 操做系統範疇,再也不贅述。
cgroup_parent
可選地爲容器指定一個上級 cgroup
。cgroup
也是 Linux 容器化實現的最重要的基本概念之一。
cgroup_parent: m-executor-abcd
複製代碼
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。
command
覆蓋容器內默認的 command
.
command: bundle exec thin -p 3000
複製代碼
command
也能夠被指定爲一個列表。實際上這也是更被推薦的方式,無歧義並且安全,並且和 dockerfile 中的格式具備一致性:
command: ["bundle", "exec", "thin", "-p", "3000"]
複製代碼
爲每一個服務提供具體化的訪問 config
的權限。
一個 config
包含一系列的配置信息,這些信息可能被經過多種途徑所建立。容器的部署引用這些配置時,能夠更好地區格諸如生產環境參數這樣的問題。另外一方面,敏感信息也所以能夠被單獨隔離到一個安全的區域中,在必定程度上減小了泄露的可能性。
NOTE: 指定的配置必須已經存在,或者已經被定義在頂級
configs
中了(defined in the top-levelconfigs
configuration)。不然整個容器棧的部署將會失敗。
支持兩個不一樣的語法變體格式。更詳盡的信息應參考 configs。
只指定配置名。容器所以能夠訪問配置 /<config_name
和掛載它(掛載的源和目標均爲該配置名)。
version: "3.8"
services:
redis:
image: redis:latest
deploy:
replicas: 1
configs:
- my_config
- my_other_config
configs:
my_config:
file: ./my_config.txt
my_other_config:
external: true
複製代碼
上面的例子使用短格式在 redis
容器的服務中定義了 my_config
和 my_other_config
的引用。這裏的 my_config
指定爲一個宿主機文件 ./my_config.txt
,而 my_other_config
被指定爲外部的(資源),這意味着相應的資源已經在 Docker 中被定義了,或許是經過 docker config create
創建的,又或者是被別的容器棧部署所創建的。
若是外部資源找不到,那麼容器棧的部署將會失敗,而且拋出一個 config not found
的錯誤。
Note:
config
定義僅在 v3.3 及更高版本的 docker-compose 格式中被支持。
長格式提供更多的信息來表述一個 config
在哪兒,如何被找到,怎麼被使用:
source
: 配置名
target
: 該配置將被掛載到容器中的路徑。默認爲 /<source>
uid
& gid
: 數字值的 Linux/Unix UID
和 GID
,若是沒有指定則爲0。Windows中不支持。
mode
: 8進制的文件權限。默認值爲 0444
。
配置是不可寫的,由於它們被掛載於臨時的文件系統中。所以若是你設置了寫許可,這將被忽略。
可執行位是能夠被設置的。
下面的例子相似於短格式的例子:
version: "3.8"
services:
redis:
image: redis:latest
deploy:
replicas: 1
configs:
- source: my_config
target: /redis_config
uid: '103'
gid: '103'
mode: 0440
configs:
my_config:
file: ./my_config.txt
my_other_config:
external: true
複製代碼
在這裏,redis
容器的服務並未訪問 my_other_config
。
你能夠受權一個服務訪問多個配置,你也能夠混用長短格式。
(在頂級)定義一個配置(config
)並未隱含着某個服務就能訪問到它。
container_name
指定一個自定義的容器名,而不是由 docker-compose 本身生成一個默認的。
container_name: my-web-container
複製代碼
因爲 Docker 容器名必須是惟一的,因此你沒法伸縮一個自定義了容器名的服務。
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。
credential_spec
since v3.3
從 v3.8 開始支持被用於組管理服務帳戶 gMSA(group Managed Service Account)方式。
爲受控服務帳戶配置憑據。這個選項只被用於 Windows 容器服務。credential_spce
只能使用格式 file://<filename>
or registry://<value-name>
。
當使用 file:
時,被參考的文件必須被置於 Docker 數據文件夾(一般是 C:\ProgramData\Docker\
)的 CredentialSpec
子目錄之下。下面的例子將會從 C:\ProgramData\Docker\CredentialSpecs\my-credential-sp
載入憑據信息:
credential_spec:
file: my-credential-spec.json
複製代碼
當使用 registry:
時,憑據信息將會被從 Docker daemon 主機的 Windows Registry 中讀入。一個註冊表表項必須位於:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs
複製代碼
之中。
下面的例子讀入 my-credential-spec
註冊表項值:
credential_spec:
registry: my-credential-spec
複製代碼
當爲一個服務配置 gMSA 憑據時,參考以下的例子:
version: "3.8"
services:
myservice:
image: myimage:latest
credential_spec:
config: my_credential_spec
configs:
my_credentials_spec:
file: ./my-credential-spec.json|
複製代碼
depends_on
表示服務之間的依賴關係。服務依賴引起以下的行爲:
docker-compose up
按照依賴順序依次啓動服務。在下面的例子中,db
和 redis
先於 web
被啓動。docker-compose up SERVICE
自動包括了 SERVICE
的依賴項。在下面的例子中,docker-compose up web
將會自動啓動 db
和 redis
。docker-compose stop
按照依賴順序依次中止服務。在下面的例子中,web
將會被先於 db
和 redis
被中止。簡單的示例以下:
version: "3.8"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
複製代碼
使用
depends_on
時應該注意的幾件事:
depends_on
並不意味着等待db
和redis
就緒後才啓動web
,而是在它們被啓動後就會接着啓動web
。若是要想等到服務就緒可用,應該參閱 Controlling startup order。版本 3 再也不支持
condition
表述。
depends_on
選項在部署到 swarm mode 時被忽略。
deploy
Version 3 only.
指定和部署以及運行相關的配置。
只會對部署到一個使用 docker stack deploy 的 swarm 有影響。
在 docker-compose up
和 docker-compose run
時被忽略。
version: "3.8"
services:
redis:
image: redis:alpine
deploy:
replicas: 6
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
複製代碼
幾個子選項是可用的:
endpoint_mode
swarm.
Since Version 3.2.
指定外部客戶端鏈接到一個 swarm 集羣時使用的服務發現方法。
endpoint_mode: vip
- Docker 爲服務請求一個虛擬IP(VIP
)用於訪問。
Docker在客戶端和服務的有效的工做節點之間對請求進行自動負載均衡路由。客戶端無需知道服務有多少可用節點,也沒必要知道服務節點的IP地址和端口號。
這是默認方式。
endpoint_mode: dnsrr
- 使用 DNS round-robin (DNSRR) 算法進行服務發現。Docker會爲服務設置一個DNS條目,於是在進行對應的 DNS 解析時經過服務名稱會返回一個IP地址清單。客戶端所以直接選擇一個具體的端點進行訪問。
version: "3.8"
services:
wordpress:
image: wordpress
ports:
- "8080:80"
networks:
- overlay
deploy:
mode: replicated
replicas: 2
endpoint_mode: vip
mysql:
image: mysql
volumes:
- db-data:/var/lib/mysql/data
networks:
- overlay
deploy:
mode: replicated
replicas: 2
endpoint_mode: dnsrr
volumes:
db-data:
networks:
overlay:
複製代碼
endpoint_mode
的選項也被一樣地用做 swarm mode 命令行選項(參閱 docker service create
)。至於 docker swarm命令的一個快捷清單,能夠查閱 Swarm mode CLI commands。
要學習更多關於 swarm mode 的網絡模型已經服務發現機制 的知識,請查看 Configure service discovery。
labels
爲服務指定標籤。這些標籤只被做用於對應的服務,而不是被應用到服務的容器或者容器實例上。
version: "3.8"
services:
web:
image: web
deploy:
labels:
com.example.description: "This label will appear on the web service"
複製代碼
要爲容器設置標籤的話,在 deploy
以外爲服務指定 labels
:
version: "3.8"
services:
web:
image: web
labels:
com.example.description: "This label will appear on all containers for the web service"
複製代碼
mode
能夠是 global
或 replicated
。global
表示嚴格地一個 swarm node 跑一個服務,replicated
表示能夠跑多個容器實例。默認是 replicated
。
參閱 swarm 主題下的 Replicated and global services。
version: "3.8"
services:
worker:
image: dockersamples/examplevotingapp_worker
deploy:
mode: global
複製代碼
placement
指定 constaints 和 preferences。
參閱docker服務創建的相關文檔以瞭解更多的關於 constraints 和 [preferences 的相關信息,包括相應的語法,可用的類型等等的完整描述。
version: "3.8"
services:
db:
image: postgres
deploy:
placement:
constraints:
- node.role == manager
- engine.labels.operatingsystem == ubuntu 14.04
preferences:
- spread: node.labels.zone
複製代碼
max_replicas_per_node
Since version 3.8.
若是一個服務是可副本的 replicated
(這是默認的), max_replicas_per_node 將會 限制副本數量(limit the number of replicas) 。
當太多任務申請新的任務節點且超出了 max_replicas_per_node 限制值時,一個 no suitable node (max replicas per node limit exceed)
錯誤將會被拋出。
version: "3.8"
services:
worker:
image: dockersamples/examplevotingapp_worker
networks:
- frontend
- backend
deploy:
mode: replicated
replicas: 6
placement:
max_replicas_per_node: 1
複製代碼
replicas
若是服務是 replicated
的,replicas
則爲其指定一個數值,此數值指示了一個 swarm 節點上最多能夠跑多少個容器實例。
version: "3.7"
services:
worker:
image: dockersamples/examplevotingapp_worker
networks:
- frontend
- backend
deploy:
mode: replicated
replicas: 6
複製代碼
resources
配置資源約束。
NOTE: 對於非 swarm mode 而言,這個表項替換 older resource constraint options(諸如
cpu_shares
,cpu_quota
,cpuset
,mem_limit
,memswap_limit
,mem_swappiness
等在版本3以前版本中的表項)。在 Upgrading version 2.x to 3.x 中有相應的描述。
這些資源約束表項都具備一個單一值,至關於 docker service create
中的等價物。
在以下的例子中,redis
服務被約束爲不可以使用超出50M的內存,單核50%的CPU使用率,同時也保留 20M 內存以及 25%的CPU使用率做爲基準值。
version: "3.8"
services:
redis:
image: redis:alpine
deploy:
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
複製代碼
如下的主題描述 swarm 場景下的服務或容器資源約束的可用選項。
企圖在你的服務和容器實例中使用超過系統擁有的內存,那麼將獲得 Out Of Memory Exception (OOME) 。此時,容器實例,或者 Docker daemon,可能會被內核的 OOM 管理器所清除。
要防止這樣的狀況發生,請肯定你的應用程序合法有效地使用內存。對於這樣的風險,查閱 Understand the risks of running out of memory 以獲知進一步的評估須知。
restart_policy
指示當容器實例退出時,如何重啓。替換 restart
:
condition
: 能夠爲 none
, on-failure
或 any
(默認爲 any
)delay
: 在嘗試重啓以前的等候時長(默認爲0)。應該爲其指定一個 duration。max_attempts
: 試圖嘗試重啓多少次後放棄重啓的嘗試。默認爲不放棄。window
: 要肯定一次重啓是否成功,須要等候的時長。默認爲無等待當即認定爲已成功。應該爲其指定一個 duration。version: "3.8"
services:
redis:
image: redis:alpine
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
複製代碼
rollback_config
Version 3.7 file format and up
在滾動更新失敗的場景下服務應該如何回滾:
parallelism
:同時回滾的容器的數量值。若是設置爲0,全部容器將被同時回滾。delay
: 每一個容器組被回滾前的等待時長(默認爲0)failure_action
: 一個回滾失敗時應當執行的動做。能夠是 continue
或 pause
(默認爲pause
)monitor
: 失敗的回滾狀態被更新到監視器的週期(ns|us|ms|s|m|h
)默認爲 0s
。max_failure_ratio
: 回滾時失敗的可容忍的比例(默認爲0)order
: 回滾的操做順序。能夠爲 stop-first
或 start-first
(默認爲 stop-first
)update_config
指示服務應該如何被更新。這對於配置爲滾動更新時有用:
parallelism
:同時更新的容器的數量值。若是設置爲0,全部容器將被同時回滾。delay
: 每一個容器組被更新前的等待時長(默認爲0)failure_action
: 一個更新失敗時應當執行的動做。能夠是 continue
, rollback
或 pause
(默認爲pause
)monitor
: 失敗的更新狀態被更新到監視器的週期(ns|us|ms|s|m|h
)默認爲 0s
。max_failure_ratio
: 更新時失敗的可容忍的比例(默認爲0)order
: 更新的操做順序。能夠爲 stop-first
或 start-first
(默認爲 stop-first
)NOTE:
order
只在 v3.4 及以後有效。
version: "3.8"
services:
vote:
image: dockersamples/examplevotingapp_vote:before
depends_on:
- redis
deploy:
replicas: 2
update_config:
parallelism: 2
delay: 10s
order: stop-first
複製代碼
DOCKER STACK DEPLOY
不支持者下列的子選項(爲 docker-compose up
和 docker-compose run
所支持)是在 docker stack deploy
中不被支持的:
Tip: 請參閱 如何爲 service 服務模式和 swarm 集羣模式使用卷而配置 docker-stack.yml 文件 - how to configure volumes for services, swarms, and docker-stack.yml files 章節。 Volumes(卷)在 swarms 模式和 services 模式中是被支持的,但你只能採用命名卷,又或是與受約束於有權訪問必需卷的節點的服務關聯.
devices
要被映射的設備清單。其用法和 docker 命令的 --device
相同。
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
複製代碼
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。
dns
自定義 DNS 服務器列表。能夠指定單一值或一個清單。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
複製代碼
dns_search
自定義DNS搜索域名。能夠指定單一值或一個清單。
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
複製代碼
entrypoint
覆蓋 dockerfile 中定義的默認的 entrypoint 值。
entrypoint: /code/entrypoint.sh
複製代碼
入口點也能夠是一個清單:
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit
複製代碼
NOTE: 設置一個
entrypoint
不但覆蓋 Dockerfile 中的任何ENTRYPOINT
默認值,還會清理 Dockerfile 中的任何CMD
默認值。因此 Dockerfile 中的CMD
將會被忽略。
env_file
從給定的文件中引入環境變量值。能夠是單一值或一個清單。
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
複製代碼
對於 docker-compose -f FILE
來講,env_file
的路徑是相對於 FILE
所在文件夾的。
在 environment
中聲明的環境變量將會覆蓋掉這裏所引入的值。
對應的文件中,每一行應該使用 VAR=VAL
格式定義一個環境變量。行首爲 #
表示爲註釋行,和空白行同樣被忽略。
# Set Rails/Rack environment
RACK_ENV=development
複製代碼
NOTE: 若是服務定義了
build
項,在構建過程當中,由env_file
所定義的環境變量並不可見。只能使用build
的子選項args
去定義構建時環境變量值。
VAL
的值被原樣照用,且不能被修改。例如若是值由引號所包圍,那麼值的表示量中也包含引號。
環境變量文件的順序也須要被注意。位置靠後的環境變量文件中所定義的變量值會覆蓋掉早前定義的舊值。
按:原文居然說了這麼多!
Keep in mind that the order of files in the list is significant in determining the value assigned to a variable that shows up more than once. The files in the list are processed from the top down. For the same variable specified in file
a.env
and assigned a different value in fileb.env
, ifb.env
is listed below (after), then the value fromb.env
stands. For example, given the following declaration indocker-compose.yml
:
services:
some-service:
env_file:
- a.env
- b.env
複製代碼
And the following files:
# a.env
VAR=1
複製代碼
and
# b.env
VAR=hello
複製代碼
$VAR
is hello
.
environment
添加環境變量。可使用一個數組或者一個字典。任何布爾量:true, false, yes, no 等等都必須用引號包圍爲字符串字面量。
只有key值的環境變量的value值依賴於 docker-compose 運行時的主機環境,這對於防止敏感信息泄露是有用的。
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
# 或
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
複製代碼
NOTE: 若是服務定義了
build
項,在構建過程當中,由env_file
所定義的環境變量並不可見。只能使用build
的子選項args
去定義構建時環境變量值。
expose
暴露端口到連接的服務。這些端口並不會被髮布到宿主機。只能指定內部端口被用於暴露。
expose:
- "3000"
- "8000"
複製代碼
external_links
將在 docker-compose.yml
以外啓動的容器連接到給定服務上。
和遺留選項 links
有類似的語義。
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
複製代碼
Note
在 docker-compose.yml 以外創建的容器(The externally-created containers)必須至少鏈接到一個相同的網絡,才能與一個定義在 docker-compose.yml 中的服務相連接 。Links 選項已通過時了,咱們推薦使用 networks 來代替它。
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。
更推薦的作法是經過 networks
構造一個子網以進行容器之間的連接。
extra_hosts
添加主機名映射。這些映射關係會被添加到 /etc/hosts
中。此功能等價於命令行參數 --add-host
。
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
複製代碼
對於這個服務來講,在容器中的 /etc/hosts
文件中,相應的主機名及其IP將被創建爲一個條目。例如:
162.242.195.82 somehost
50.31.209.229 otherhost
複製代碼
healthcheck
since v2.1
用於確認一個服務是不是「健康」的。參閱 HEALTHCHECK Dockerfile instruction。
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
複製代碼
interval
, timeout
和 start_period
應該被指定爲 durations.
Note:
start_period
只在 v3.4 及之後可用。
test
必須是一個單一字符串值或一個列表。若是是一個列表,那麼第一項必須是 NONE
, CMD
, CMD-SHELL
之一。若是是一個字符串,隱含地表示一個 CMD-SHELL
前綴。
# Hit the local web app
test: ["CMD", "curl", "-f", "http://localhost"]
複製代碼
如上述示例,但隱含調用 /bin/sh
,和如下的形式是等效的。
test: ["CMD-SHELL", "curl -f http://localhost || exit 1"]
test: curl -f https://localhost || exit 1
複製代碼
要禁用任何在映像內指定的缺省的健康檢查向,可使用 disable: true
。這和指定 test: ["NONE"]
是等效的。
healthcheck:
disable: true
複製代碼
image
指定映像的名稱。
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd
複製代碼
若是映像在宿主機不存在,Compose 會嘗試下拉它,除非你也指定了 build
項。
init
since v3.7
在容器中運行一個 init 進程並轉發信號。設置爲 true
爲服務使能這個特性。
version: "3.8"
services:
web:
image: alpine:latest
init: true
複製代碼
缺省的 init 進程使用二進制執行文件 Tini,在須要時它將被安裝於 daemon主機的位置
/usr/libexec/docker-init
。你也能夠配置 daemon 使用一個不一樣的二進制文件,經過init-path
,參閱 configuration option。
isolation
指定一個容器的隔離層級/技術。在 Linux 中,僅支持 default
值。在 Windows 中,能夠接受的值有:default
, process
和 hyperv
。
labels
爲容器添加元數據標籤,參考 Docker labels。能夠爲其指定一個數組或一個字典。
咱們建議你採用反向DNS標註方式來定義你的標籤,這能夠有效地避免標籤名稱的衝突。
labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
複製代碼
links
已是一個遺留特徵了。在不久的將來將被移除。
按:因此我也不精確翻譯了:) 太囉嗦了。
連接另外一個服務到本容器。能夠同時制定服務名稱和連接別名(SERVICE:ALIAS
),也能夠略過連接別名。
web:
links:
- db
- db:database
- redis
複製代碼
已經被鏈入的服務將會是主機名(即連接別名 ALIAS
)可訪問的。
對於服務間通信來講,連接並非必須的。默認狀況下,任何服務均可以經過服務名訪問到其餘服務。參閱 Links topic in Networking in Compose。
連接也表示一個依賴關係,但這已是 depends_on
的任務了,因此連接也並沒必要要了。
logging
爲服務指定日誌轉發配置。
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
複製代碼
driver
指定了驅動名稱,這和 --log-driver
是等效的。
缺省值爲 json-file
。
driver: "json-file"
driver: "syslog"
driver: "none"
複製代碼
Note
使用
docker-compose up
和docker-compose logs
檢索日誌時,只有json-file
和journald
驅動格式的日誌才能被打印到控制檯,其餘日誌驅動程序會將日誌轉發到對應的目的地,本地將不會檢索到任何日誌輸出信息。
可用的轉發驅動器能夠參考 docs.docker.com/config/cont…
使用 option
指定驅動器的選項,如同 --log-opt
那樣。例如爲 syslog
這樣指定:
driver: "syslog"
options:
syslog-address: "tcp://192.168.0.42:123"
複製代碼
缺省的日誌轉發驅動爲 json-file
。對此能夠指定日誌切割尺寸以及最多保持的日誌歷史文件個數:
options:
max-size: "200k"
max-file: "10"
複製代碼
上面顯示的這個例子中,日誌的文件存儲將被限制爲 200kB,而且在超出時會被截斷到舊歷史日誌,這樣的歷史文件將被限制爲不超過 10 個,更舊的歷史文件將被拋棄。
這裏有一個完整的 docker-compose.yml
文件實例,演示瞭如何限制日誌存儲空間:
version: "3.8"
services:
some-service:
image: some-service
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
複製代碼
有效可用的日誌選項有賴於具體使用的日誌驅動程序。
上面的控制日誌文件個數及其大小的日誌選項,適用於 json-file driver。它們可能並不適用於別的日誌驅動程序。要了解完整的針對每一個日誌驅動程序可用的日誌選項,請查閱 logging drivers 文檔。
network_mode
網絡模型。
和 --network
的取值相同。但額外支持 service:[service name]
模式。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
複製代碼
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。
NOTE:
network_mode: "host"
不能和 links 混用。
networks
要加入的網絡。目標網絡是在 docker-compose.yml
頂級的 networks
項中定義的。
services:
some-service:
networks:
- some-network
- other-network
複製代碼
指定網絡中該服務的別名(也即主機名)。相同網絡中別的容器可使用服務名或者服務別名來鏈接到該服務的容器實例。
既然 aliases
是網絡範圍(網絡域)內的,同一個服務在不一樣網絡中能夠有不一樣的別名。
Note
一個網絡域別名,能夠被多個容器、甚至是多個服務所共享——你能夠在不一樣容器、不一樣服務之間使用重名的別名。若是你這麼作了,別名會被解決爲哪一個肯定的容器是沒法保證的。
別名定義的格式如同這樣:
services:
some-service:
networks:
some-network:
aliases:
- alias1
- alias3
other-network:
aliases:
- alias2
複製代碼
一個更復雜而完整的例子:下面提供了三個服務:``web,
worker, 和
db,分別屬於兩個網絡:
new和
legacy。經過
new網絡中的主機名
db或
database來訪問,或者
legacy網絡的主機名
db或
mysql,均可以訪問到
db` 服務。
version: "3.8"
services:
web:
image: "nginx:alpine"
networks:
- new
worker:
image: "my-worker-image:latest"
networks:
- legacy
db:
image: mysql
networks:
new:
aliases:
- database
legacy:
aliases:
- mysql
networks:
new:
legacy:
複製代碼
指定一個靜態IP地址。
注意相應的頂級網絡配置中,必須有 ipam
塊對子網進行了配置且靜態IP地址符合該子網定義。
If IPv6 addressing is desired, the
enable_ipv6
option must be set, and you must use a version 2.x Compose file. IPv6 options do not currently work in swarm mode.
一個例子是:
version: "3.8"
services:
app:
image: nginx:alpine
networks:
app_net:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10
networks:
app_net:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
- subnet: "2001:3984:3989::/64"
複製代碼
pid
pid: "host"
複製代碼
設置服務使用主機的 PID 模式。這使得容器內的服務進程和宿主機操做系統級可以共享 PID 地址空間。這是一個典型的 Linux/Unix 操做系統概念,所以這裏再也不展開敘述了。這樣的共享的做用,可使能安全的、藉助PID地址空間的 IPC 通信。
ports
暴露端口到宿主機。
Note: 端口暴露功能和
network_mode: host
不能兼容。
能夠同時指定宿主機和容器端口 (HOST:CONTAINER
) 以完成映射,也能夠僅指定容器端口以自動映射爲相同的主機端口一個臨時端口(從32768開始)。
Note
當採用
HOST:CONTAINER
格式來映射端口時,若是使用的容器端口小於60的話,你可能會接受到一個錯誤。這是由於 YAML 解析器將格式xx:yy
視爲一個 60 進制的數值。這挺荒謬的,是否是?因爲這個緣由,咱們不得不推薦你在端口號這裏老是使用引號作包圍,令其成爲一個 string 值,以避免收到不如預期的反應。
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "6060:6060/udp"
複製代碼
容許進行冗長的定義:
target
: 指定容器內的端口號published
: 指定暴露給 docker 宿主機的端口號protocol
: 協議 (tcp
or udp
)mode
: host
表示每一個節點的端口號都發布爲宿主機端口,ingress
專用於 swarm 集羣,全部節點的端口會被負載均衡爲宿主機端口。ports:
- target: 80
published: 8080
protocol: tcp
mode: host
複製代碼
意義明顯,因此略過解說。
NOTE:長格式僅在 v3.2 及以後有效。
restart
no
是默認的重啓策略。此時不管容器怎麼退出、怎麼失敗也不會被自動重啓。
指定 always
時任何狀況下容器都會被重啓。
on-failure
策略可在容器失敗退出時才重啓。
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
複製代碼
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。(此時可使用
restart_policy
達到目的)
secrets
從每一個服務配置中,受權訪問頂級 secrets
定義的表項。支持長短兩個格式。
短格式僅指定敏感內容的名字。這使得容器可以掛載對應內容到 /run/secrets/<secret_name>
位置並訪問它。
下面的例子使用短格式,讓 redis
可以訪問 my_secret
和 my_other_secret
。my_secret
的具體內容被定義在 ./my_secret.txt
,my_other_secret
被定義爲外部資源,例如經過 docker secret create
方式預先定義。若是找不到對應的外部資源,stack部署將會失敗並拋出一個 secret not found
錯誤。
version: "3.8"
services:
redis:
image: redis:latest
deploy:
replicas: 1
secrets:
- my_secret
- my_other_secret
secrets:
my_secret:
file: ./my_secret.txt
my_other_secret:
external: true
複製代碼
長格式能夠更精細地定義敏感內容如何被用於 stack 內容器。
source
: 敏感內容在 Docker 中所被定義的名字。target
: 被掛載到容器內 /run/secrets/
中的文件名。若是沒指定則使用 source
名。uid
& gid
: 容器內掛載的文件的 UID 和 GID。如未指定則爲0。在 Windows 中無效。mode
: 容器內掛載的文件的八進制許可權限。在 Docker 1.13.1 中默認值爲 0000
,但在更新的版本中爲 0444
。掛載的文件是不可寫的。執行位能夠被設置,但通常狀況下沒有意義。下面是一個例子:
version: "3.8"
services:
redis:
image: redis:latest
deploy:
replicas: 1
secrets:
- source: my_secret
target: redis_secret
uid: '103'
gid: '103'
mode: 0440
secrets:
my_secret:
file: ./my_secret.txt
my_other_secret:
external: true
複製代碼
長短格式時能夠被混用的,若是你在定義多個敏感內容。
security_opt
爲每一個容器覆蓋掉默認的標籤語義。
security_opt:
- label:user:USER
- label:role:ROLE
複製代碼
一般這和 seccomp 有關,這會是與安全配置有關的一個冗長的話題,故而此處不作展開。
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。
指定一個等待時長,若是容器未能攔住 SIGTERM
信號(或者經過 stop_signal
定義的別的信號)正常地關閉本身,則在此時長以後強制清除容器實例的相應進程(經過 SIGKILL
信號)。
stop_grace_period: 1s
stop_grace_period: 1m30s
複製代碼
默認時,將會等候 10s 。
stop_signal
設置一個替代信號以正常關閉容器實例。默認時使用 SIGTERM
信號.
stop_signal: SIGUSR1
複製代碼
sysctls
爲容器設定內核參數。可使用一個數組或字典。
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
複製代碼
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。
tmpfs
v2 的解說在 v3.8 的原文裏已經被刪除了:
since v2
掛載一個臨時文件系統到容器中。能夠是一個單一值或一個列表。
tmpfs: /run tmpfs: - /run - /tmp 複製代碼
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。
since v3.6
掛載一個臨時文件系統到容器中。可使用一個單一值或一個數組。
tmpfs: /run
tmpfs:
- /run
- /tmp
複製代碼
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。
掛載一個臨時文件系統到容器中。Size參數能夠指定文件系統尺寸的字節大小。默認值爲無限。
- type: tmpfs
target: /app
tmpfs:
size: 1000
複製代碼
ulimits
覆蓋容器內指定的默認的 ulimits 值。能夠指定一個整數做爲單一的 limit 限制,或者指定一個 mapping 以分別表示 soft/hard limit 限制。
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
複製代碼
userns_mode
userns_mode: "host"
複製代碼
禁用用戶名字空間。若是 Docker daemon 被配置運行在一個 user namespace 之中的話。
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。
volumes
掛載宿主機路徑或者命名卷。
能夠掛載一個主機路徑到一個服務中,此時無需在頂級 volumes
中對其進行定義。
若是想要重用一個捲到多個服務,那麼應該在頂級 volumes
中定義它並命名它。
能夠在 services, swarms, and stack files 中使用命名卷。
NOTE: 在頂級
volumes
中定義一個命名卷,並在一個服務的volumes
列表中引用它。早期的
volumes_from
再也不使用了。能夠參閱 Use volumes and Volume Plugins。
下面的例子示意了一個命名卷 my_data
,且被用於 web
服務。在 web
中也使用一個主機文件夾 ./static
到容器內的掛載;在 db
中掛載了一個主機文件到容器內的對應文件,並使用了另外一個命名卷 dbdata
。
version: "3.8"
services:
web:
image: nginx:alpine
volumes:
- type: volume
source: mydata
target: /data
volume:
nocopy: true
- type: bind
source: ./static
target: /opt/app/static
db:
image: postgres:latest
volumes:
- "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"
- "dbdata:/var/lib/postgresql/data"
volumes:
mydata:
dbdata:
複製代碼
Note
關於卷的更多信息,請參閱 use volumes 和 volume plugins 章節。
可使用 HOST:CONTAINER
格式,或者附帶一個訪問模式 HOST:CONTAINER:ro
。
短格式的語法爲 [SOURCE:]TARGET[:MODE]
。SOURCE
能夠是一個主機路徑,也能夠是一個卷名。TARGET
是一個容器內路徑 T,主機路徑將被掛載到該路徑 T。MODE
能夠是 ro
或者 rw
,分別表明着 只讀 和 可讀寫。
能夠掛載一個主機中的相對路徑,此路徑是相對於 docker compose 文件而被展開的。相對路徑應該老是以 .
或者 ..
開始。
volumes:
# Just specify a path and let the Engine create a volume
- /var/lib/mysql
# Specify an absolute path mapping
- /opt/data:/var/lib/mysql
# Path on the host, relative to the Compose file
- ./cache:/tmp/cache
# User-relative path
- ~/configs:/etc/configs/:ro
# Named volume
- datavolume:/var/lib/mysql
複製代碼
長格式能夠進行更精細的控制。
type
: 掛載類型 爲 volume
, bind
, tmpfs
和 npipe
source
:掛載的源位置。能夠是一個主機路徑,一個定義於頂級 volumes 中的卷名稱,等等。若是是掛載 tmpfs
則此參數無心義。target
: 容器內的掛載點路徑。read_only
: 布爾值以設定卷的可寫性。bind
: 配置附加的 bind 選項。
propagation
: 用於 bind 的傳播模式。volume
: 配置附加的 卷 選項
nocopy
:布爾量以禁用數據複製(默認時當卷被首次建立時,容器內的內容將被複制到卷內)tmpfs
: 配置附加的 tmpfs 選項
size
: tmpfs的容量,按字節數。consistency
:掛載的一致性要求:consistent
主機和容器有一樣的視圖,cached
讀操做被緩衝,主機視圖爲主體,delegated
讀寫操做被緩衝,容器視圖爲主體。version: "3.8"
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- type: volume
source: mydata
target: /data
volume:
nocopy: true
- type: bind
source: ./static
target: /opt/app/static
networks:
webnet:
volumes:
mydata:
複製代碼
長格式在 v3.2 以後可用Note
在作綁定主機目錄並掛載到容器操做時,長格式語法須要你提早將主機文件夾準備就緒。使用短格式的話,對應文件夾將被就地建立,若是它還沒有存在的話。詳情請參閱 bind mounts documentation。
當工做在 services, swarms, 或 docker-stack.yml
場景下,要注意一個服務在 swarm 中可能被部署到任意節點,而每當服務被更新以後再次啓動時,可能已經再也不在原來的節點上了。
當指定名稱的卷並不存在時,Docker會自動建立一個匿名卷用於引用的服務。匿名卷是不可持久化的,所以當關聯的容器實例退出並被移除時,匿名卷也會被銷燬。
若是想要持久化你的數據,採用命名卷以及選擇恰當的卷驅動程序,這個驅動應該是跨主機的,這樣數據才能在不一樣的主機之間漫遊。不然的話,你應該設置服務的約束條件以便該服務只會被部署到特定的節點上,這些節點上有相應的卷服務在正確工做。
做爲一個例子,votingapp sample in Docker Labs 的 docker-stack.yml
文件定義了 db
服務,運行着 postgresql。它使用了一個命名卷 db-data
來持久化數據庫數據,這個卷被經過swarm約束在只能運行在 manager
這個節點上,所以一切疑難都不存在了。下面是源碼:
version: "3.8"
services:
db:
image: postgres:9.4
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
deploy:
placement:
constraints: [node.role == manager]
複製代碼
在 Docker 17.04 CE Edge 以及其後版本中(乃至於 17.06CE Edge 和 Stable 版本),你能夠配置容器和主機之間卷如何被同步的一致性約束參數。這些標誌包括:
consistent
徹底一致。主機和容器有一樣的視圖,這是默認的策略。
cached
宿主機爲準。對卷的讀操做被緩衝,主機視圖爲主體,
delegated
容器爲準。對卷的讀寫操做被緩衝,容器視圖爲主體。
這是專爲 Docker Desktop for Mac 而適配的。因爲已經知道的 osxfx
的關於文件共享特性緣由,合理的設置一致性標誌可以改善容器內外訪問掛載卷時的性能問題。
下面是一個cached
卷的例子:
version: "3.7"
services:
php:
image: php:7.1-fpm
ports:
- "9000"
volumes:
- .:/var/www/project:cached
複製代碼
對於讀寫操做均被緩衝的狀況,即便容器中發生了什麼修改(對於向PHP Website這樣的典型架構來講,./config.php 常常是可能被寫入的),也不會當即體現到宿主機中來,容器中的寫入將會被堆積。
卷在容器內外的一致性問題,應該參考 Performance tuning for volume mounts (shared filesystems)。
在這裏我未能原樣翻譯,由於那樣會帶來較長的篇幅,我還沒有能就此問題組織好語言。
domainname
, hostname
, ipc
, mac_address
, privileged
, read_only
, shm_size
, stdin_open
, tty
, user
, working_dir
這些配置具備單一值。和 docker run
的相應命令行參數相對應。mac_address
已是被遺棄的設定。
user: postgresql
working_dir: /code
domainname: foo.com
hostname: foo
ipc: host
mac_address: 02:42:ac:11:65:43
privileged: true
read_only: true
shm_size: 64M
stdin_open: true
tty: true
複製代碼
有的配置選項,例如 interval
或者 timeout
(都是 check
的子選項),接受一個字符串風格的時間週期或時間段的參數值。它們應該具備這樣的格式:
2.5s
10s
1m30s
2h32m
5h34m56s
複製代碼
能夠爲數值附加的後綴單位有 us
, ms
, s
, m
, 以及 h
。
含義自明。
有的配置選項,例如 build
的子選項 shm_size
,接受一個字符串分隔的容量尺寸參數值。它們應該具備這樣的格式:
2b
1024kb
2048k
300m
1gb
複製代碼
有效的後綴單位包括 b
, k
, m
和 g
。此外,kb
, mb
和 gb
也是合法的。純粹的十進制數值並不合法。
volumes
頂級的 volumes 章節能夠聲明和建立命名卷(無需使用 volume_from
),這些卷可以被用於在 service 章節下的 volumes 小節中被引用。因此咱們能夠重用它們,甚至可以跨越多個 services。docker命令的 docker volume 子命令有更多的參考信息。
關於卷的使用,也能夠參考 Use volumes 和 Volume Plugins。
這裏有一個示例,包含了兩個服務,數據庫的數據存儲文件夾在兩個服務之間被共享,於是數據庫可使用這個存儲文件夾,而備份服務一樣能夠操做它以完成備份任務:
version: "3.8"
services:
db:
image: db
volumes:
- data-volume:/var/lib/db
backup:
image: backup-service
volumes:
- data-volume:/var/lib/backup/data
volumes:
data-volume:
複製代碼
頂級 volumes
章節下的條目能夠是空,無需指定細節,這樣的話,默認的卷驅動程序將被應用(一般都會是 local
卷驅動)。
但你也能夠經過下面的參數對其進行定製:
driver
指定哪個卷驅動程序會被採用。通常來講,默認值會是 local
。若是卷驅動程序無效、或不能工做,在 docker-compose up
時 Docker Engine將會返回一個錯誤。
driver: foobar
複製代碼
driver_opts
可選地指定一組鍵值對參數集,這些參數將被傳遞給卷驅動程序。因此這些參數集是和卷驅動程序相關的,請參考卷驅動程序的有關文檔。
volumes:
example:
driver_opts:
type: "nfs"
o: "addr=10.40.0.199,nolock,soft,rw"
device: ":/docker/example"
複製代碼
external
若是設置爲 true
,表示相應的卷是在 compose 編排文件以外被建立就緒的。此時 docker-compse up
將不會嘗試建立這個卷,而若是該卷還沒有存在則會返回一個錯誤。
對於 v3.3 以及更低的 compose 編排格式版本而言,external
不能夠被用於與其餘卷配置參數組合使用,例如 driver
, driver_opts
, labels
等等。但對於 v3.4 以及更高版原本說再也不有此限制。
下面的示例中,Compose 查找一個名爲 data
的外部卷並掛載它到 db
服務中,而不是嘗試建立一個名爲 [projectname]_data
的新卷。
version: "3.8"
services:
db:
image: postgres
volumes:
- data:/var/lib/postgresql/data
volumes:
data:
external: true
複製代碼
external.name
在 v3.4+ 已被廢棄,這以後直接使用name
。
你也能夠單獨指定卷名字(這時,data
被認爲是該卷在當前編排文件中被引用時的 卷別名):
volumes:
data:
external:
name: actual-name-of-volume
複製代碼
External volumes are always created with docker stack deploy
在使用 docker stack deploy 部署到 swarm 中時,外部卷若是不存在,則老是自動被建立。進一步的有關信息請參閱 moby/moby#29976、
labels
使用 Docker labels 爲容器添加元數據。能夠是數組格式或者字典格式。
咱們建議你使用反向DNS標註方式,爲你的元數據表鍵添加反向域名前綴,從而避免潛在的和其它應用的相同名字的表鍵發生衝突:
labels:
com.example.description: "Database volume"
com.example.department: "IT/Ops"
com.example.label-with-empty-value: ""
labels:
- "com.example.description=Database volume"
- "com.example.department=IT/Ops"
- "com.example.label-with-empty-value"
複製代碼
name
since v3.4+
爲卷指定一個自定義的名字。名字的值可被用於解決具備特殊字符名字的卷。注意該值被原樣使用,引號不會被忽略,也不會被添加上棧名字前綴。
version: "3.8"
volumes:
data:
name: my-app-data
複製代碼
name
能夠被與 external
相組合:
version: "3.8"
volumes:
data:
external: true
name: my-app-data
複製代碼
networks
頂級章節 networks
使得你能夠配置想要建立和使用的網絡(Compose內網)。
driver
指定該網絡的驅動程序。
缺省的驅動程序由 Docker Engine 的啓動參數所指定。一般狀況下,啓動參數內置爲在單節點宿主機上使用 bridge
驅動,而在 swarm mode
中使用 overlay
驅動。
若是驅動程序不可用,Docker Engine 將會返回一個錯誤。
driver: overlay
複製代碼
bridge
缺省時 Docker 在每一個宿主機節點上使用 bridge
驅動。有關橋接網絡是如何工做的,能夠參考 Docker Labs 的和網絡相關的輔導用例:Bridge networking。
overlay
overlay
驅動在多個 swarm mode
節點之間創建一個命名子網,這是一個跨主機的虛擬網絡。
swarm mode
中如何創建 overlay
網絡並籍此令服務跨主機正確工做,請參考 Docker Labs 的和網絡相關的輔導用例: Overlay networking and service discovery。overlay
是如何跨主機完成虛擬網絡構建和報文如何流轉的,能夠參考 Overlay Driver Network Architecture。host
或 none
使用主機網絡棧,或者不使用網絡。
和命令行參數 --net=host
以及 --net=none
是等價的。
這兩種驅動及網絡模型只能被用於 docker stack
之中。若是你正在使用 docker compose
相關指令,請使用 network_mode
來指定它們。
If you want to use a particular network on a common build, use [network] as mentioned in the second yaml file example.
使用內建的網絡模型,例如 host
和 none
,語法上有一點點須要注意的地方:若是用 host
或 none
這樣的名字定義一個外部網絡(注意你並不須要真的建立他們,這二者都屬於Docker內置的網絡模型),那麼在 Compose 編排文件中引用它們時你須要使用 hostnet
或 nonet
,如同這樣:
version: "3.8"
services:
web:
networks:
hostnet: {}
networks:
hostnet:
external: true
name: host
---
services:
web:
...
build:
...
network: host
context: .
...
services:
web:
...
networks:
nonet: {}
networks:
nonet:
external: true
name: none
複製代碼
driver_opts
指定一組鍵值對錶示的選項集,以傳遞給網絡驅動程序。它們是和驅動程序密切相關的,因此具體的可用參數應該參考對應的驅動程序文檔。
driver_opts:
foo: "bar"
baz: 1
複製代碼
attachable
since v3.2+
只能用於 driver: overlay
的場景。
若是被設置爲 true
,獨立運行的容器也能被附着在該網絡之中。若是獨立運行的容器實例被附着到了一個 overlay 網絡中,那麼容器中的服務與單獨的容器實例之間可以互相通信。請注意你甚至能夠附着其餘 Docker daemon 中的容器實例到本 overlay 網絡中。
networks:
mynet1:
driver: overlay
attachable: true
複製代碼
enable_ipv6
在該網絡/子網中啓用 IPv6。
在 v3+ 中不被支持。
enable_ipv6
須要你使用 v2 的編排格式,並且也不能被用於 swarm mode 中。
ipam
自定義 IPAM 配置。每一項子配置都是可選參數。
driver
: 自定義 IPAM 驅動程序,而不使用默認值config
: 一個列表,包含一到多個配置塊。每一個配置塊具備下列子參數:
subnet
: CIDR格式的子網定義,以劃定一個網段。一個完整的例子:
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
複製代碼
NOTE:附加IPAM如
gateway
只在 v2 中可用。
internal
默認時,Docker也會鏈接到一個橋接網絡以提供外部可鏈接性。若是你想創建一個外部的隔離的 overlay 網絡,請設置本選項爲 true
。
labels
使用 Docker labels 爲容器添加元數據。能夠是數組格式或者字典格式。
咱們建議你使用反向DNS標註方式,爲你的元數據表鍵添加反向域名前綴,從而避免潛在的和其它應用的相同名字的表鍵發生衝突:
labels:
com.example.description: "Financial transaction network"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
labels:
- "com.example.description=Financial transaction network"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
複製代碼
external
若是設置爲 true
,那麼本網絡是在 Compose 編排文件以外被建立和管理的。此時 dockercompose up
不會試圖建立它,若是網絡並不存在則返回一個錯誤。
對於 v3.3 以及更低版本的格式,external
不可與 driver
, driver_opts
, ipam
, internal
等連用。此限制在 v3.4+ 以後被取消。
下面的例子裏,proxy
是一個外部世界中的網關,Compose將會尋找經過 docker network create outside
所創建的 outside
外部網絡,而不是試圖去自動創建一個名爲 [projectname]_outside
的新網絡:
version: "3.8"
services:
proxy:
build: ./proxy
networks:
- outside
- default
app:
build: ./app
networks:
- default
networks:
outside:
external: true
複製代碼
external.name
在 v3.5 及以後已經被廢棄,請改用name
。
你也能夠單獨指定一個網絡名用於在Compose編排文件內被引用。
name
since v3.5
爲網絡設置一個自定義名字。名字的值可被用於解決具備特殊字符名字的卷。注意該值被原樣使用,引號不會被忽略,也不會被添加上棧名字前綴。
version: "3.8"
networks:
network1:
name: my-app-net
複製代碼
name
能夠與 external
一塊兒連用:
version: "3.8"
networks:
network1:
external: true
name: my-app-net
複製代碼
configs
頂級的 configs
章節聲明,定義了一個配置項或者其參考,該配置項能夠被受權給棧內服務使用。配置項的來源能夠是 file
或 external
。
file
: 配置項的內容在一個宿主機文件中。external
: 若是設置爲 true
,表示該配置項已經建立就緒了。Docker將不會試圖創建它,而是在起不存在時生成一個 config not found
錯誤。name
: 該配置項在 Docker 中的名字。名字的值可被用於解決具備特殊字符名字的卷。注意該值被原樣使用,引號不會被忽略,也不會被添加上棧名字前綴。driver
and driver_opts
: The name of a custom secret driver, and driver-specific options passed as key/value pairs. Introduced in version 3.8 file format, and only supported when using docker stack
.template_driver
: The name of the templating driver to use, which controls whether and how to evaluate the secret payload as a template. If no driver is set, no templating is used. The only driver currently supported is golang
, which uses a golang
. Introduced in version 3.8 file format, and only supported when using docker stack
. Refer to use a templated config for a examples of templated configs.下面的例子中,看成爲棧的一部分被部署時,my_first_config
會被自動建立並命名爲 <stack_name>_my_first_config
,至於 my_second_config
是已經存在的。
configs:
my_first_config:
file: ./config_data
my_second_config:
external: true
複製代碼
另外一種變化是外部配置項帶有 name
定義的狀況,此時該配置項在 Compose 中能夠被以 redis_config
爲名進行參考和使用:
configs:
my_first_config:
file: ./config_data
my_second_config:
external:
name: redis_config
複製代碼
你仍需在棧內爲每一個服務聲明 configs
章節以得到訪問配置項的權利,參考 grant access to the config。
secrets
頂級的 secrets
章節聲明,定義了一個敏感信息項或者其參考,該敏感信息項能夠被受權給棧內服務使用。敏感信息項的來源能夠是 file
或 external
。
file
: 敏感信息項的內容在一個宿主機文件中。external
: 若是設置爲 true
,表示該敏感信息項已經建立就緒了。Docker將不會試圖創建它,而是在起不存在時生成一個 secret not found
錯誤。name
: 該敏感信息項在 Docker 中的名字。名字的值可被用於解決具備特殊字符名字的卷。注意該值被原樣使用,引號不會被忽略,也不會被添加上棧名字前綴。template_driver
: The name of the templating driver to use, which controls whether and how to evaluate the secret payload as a template. If no driver is set, no templating is used. The only driver currently supported is golang
, which uses a golang
. Introduced in version 3.8 file format, and only supported when using docker stack
.下面的例子中,看成爲棧的一部分被部署時,my_first_secret
會被自動建立並命名爲 <stack_name>_my_first_secret
,至於 my_second_secret
是已經存在的。
secrets:
my_first_secret:
file: ./secret_data
my_second_secret:
external: true
複製代碼
另外一種變化是外部配置項帶有 name
定義的狀況,此時該配置項在 Compose 中能夠被以 redis_secret
爲名進行參考和使用。
secrets:
my_first_secret:
file: ./secret_data
my_second_secret:
external: true
name: redis_secret
複製代碼
my_second_secret:
external:
name: redis_secret
複製代碼
你仍需在棧內爲每一個服務聲明 secret
章節以得到訪問敏感信息項的權利,參考 grant access to the secret。
Compose編排文件中可使用環境變量。當 docker-compose
運行時,Compose 從 Shell 環境變量中抽取變量值。例如,假設操做系統的環境變量中包含 POSTGRES_VERSION=9.3
的定義,那麼如下定義
db:
image: "postgres:${POSTGRES_VERSION}"
複製代碼
等價於
db:
image: "postgres:9.3"
複製代碼
若是環境變量並不存在或者爲空串,那麼它就被當作是空字符串。
你能夠經過 .env
文件來爲環境變量設定缺省值。Compose 將會自動查找當前文件夾中的 .env
文件以得到環境變量的值。
IMPORTANT: 注意
.env
文件只在docker-compose up
場景中有效,而在docker stack deploy
時它並不會被使用。
兩種語法 $VARIABLE
和 ${VARIABLE}
都是可用的。此外在 v2.1 格式中,相似於 Shell 語法的以下形式也能夠被使用:
${VARIABLE:-default}
將會返回 default
,若是環境變量 VARIABLE
爲空字符串或未被設置的話。${VARIABLE-default}
將會返回 default
,若是環境變量 VARIABLE
未被設置的話。相似地,下面的語法有助於指定一個明確的值:
${VARIABLE:?err}
將會產生錯誤信息 err
,若是環境變量 VARIABLE
爲空或未被設置的話。${VARIABLE?err}
將會產生錯誤信息 err
,若是環境變量 VARIABLE
未被設置的話。其餘的 Shell 語法特性並未被支持,例如 ${VARIABLE/foo/bar}
。
若是須要一個美圓符號的話,請使用 $$
。此時 $$
再也不參與環境變量替換的解釋。以下例:
web:
build: .
command: "$$VAR_NOT_INTERPOLATED_BY_COMPOSE"
複製代碼
若是你忘記了這個規則而使用了一個 $
單個字符的話,Compose 會警告你:
The VAR_NOT_INTERPOLATED_BY_COMPOSE is not set. Substituting an empty string.
since v3.4
經過擴展字段,可以重用編排配置片斷。它們能夠是自由的格式,前提是你將它們定義在 yaml 文檔的頂級,而且其章節名以 x-
開頭:
version: '3.4'
x-custom:
items:
- a
- b
options:
max-size: '12m'
name: "custom"
複製代碼
NOTE
從 v3.7 開始(對於 3.x 系列),或者從 v2.4 開始(對於 2.x 系列),擴展字段也能夠被放在 服務,卷,網絡,配置項以及敏感信息項頂級章節之下的第一級。
如同這樣:
version: '3.7' services: redis: # ... x-custom: items: - a - b options: max-size: '12m' name: "custom" 複製代碼
所謂的自由格式,是指這些定義並不被 Compose 所解釋。然而當你在某個地方插入它們的引用時,它們會被展開到插入點,而後再結合上下文被 Compose 解釋具體的語義。這使用了 YAML anchors 語法。
例如,若是你的多個服務都會使用相同的日誌記錄選項:
logging:
options:
max-size: '12m'
max-file: '5'
driver: json-file
複製代碼
你能夠這樣定義:
x-logging:
&default-logging
options:
max-size: '12m'
max-file: '5'
driver: json-file
services:
web:
image: myapp/web:latest
logging: *default-logging
db:
image: mysql:latest
logging: *default-logging
複製代碼
經過 YAML merge type 語法,你也能夠在插入擴展字段定義是覆蓋某些子選項。例如:
version: '3.4'
x-volumes:
&default-volume
driver: foobar-storage
services:
web:
image: myapp/web:latest
volumes: ["vol1", "vol2", "vol3"]
volumes:
vol1: *default-volume
vol2:
<< : *default-volume
name: volume02
vol3:
<< : *default-volume
driver: default
name: volume-local
複製代碼
🔚