緣起
關於 docker-compose 的安裝,關於 docker 的基本介紹,不在本文的指導範圍內。
這篇文章基本上是 docker-compose YAML 文件格式的嚴格的英譯中。這麼做,緣起於昨天想起掃描一下 docker-compose 編排中怎麼使用 ${PWD}
的問題,結果中文沒有一點幫助,還是官網最終解決了我的模糊之處。因此我覺得還是應該做一篇比較嚴謹的譯文以及說明,來闡釋 docker-compose 編排的各項細節。
以下,我們主要是介紹 docker-compose 編排文件格式版本3 的各項細節。
閱讀本文,你應該有 docker-compose 的基本認識,至少有基本的早期(版本2)編排格式的瞭解。
關於授權
譯文從屬於原文 https://docs.docker.com/compo... 。
譯文 https://github.com/hedzr/docker-compose-file-format 本身以 MIT 方式分發。
編排格式版本3
歷史
版本3是自 docker-engine 1.13 推出以來 docker-compose 所支持的格式。這之前 docker 在 1.12 中推出了 swarm mode 來構建一個虛擬網絡中的虛擬計算資源,同時也大幅度改進了 docker 的網絡以及存儲的支持。
對於 docker-compose 編排格式與 docker-engine 之間的關係,下面這張表(摘自官網)有清晰的對照。
Compose file format | Docker Engine release |
---|---|
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"
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
章節中,你可以定義若干個服務,每個服務通常運轉着一個容器,這些服務構成了一個整體的設施棧,又或是服務羣。
一般來說我們會把一堆拉拉雜雜的東西,例如一堆微服務什麼的,編排成一個服務棧,讓他們整體對外服務,從而避免細節外露,也可以加強架構設計彈性和對整個服務棧進行伸縮(而不是面對大批微服務去逐個處理)。
編排格式手冊 - service
接下來會是一個參考手冊應有的章節結構,我們按照字母順序列列舉出了服務編排的指令,例如 ports
,volumes
,cmd
,entry
等等。
build
該選項被用於構建。
build
可以是一個指向構建上下文的路徑字符串,例如:
version: "3.7"
services:
webapp:
build: ./dir
也可以是一個更詳細的定義。這包括了 context
項所指定的路徑,以及可選的 dockerfile
文件和構建參數 args
:
version: "3.7"
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。
context
可以是一個包含 Dockerfile
的文件夾,也可以是一個指向 git repository 的 URL。
如果指定了一個相對路徑,那麼這個路徑是相對於 docker-compose.yml
文件的。這個路徑也會被傳送給 Docker daemon 用於進行構建。
docker-compose 發動構建動作和標記構建結果(按照image
名字),在那之後按照對應的名字使用它。
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"
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
多遍構建被典型地用於CI/CD。
例如步驟0可以被命名爲
builder
,負責從源碼編譯到目標文件,而步驟1則從步驟0中抽出目標文件用於部署打包,並生成最終的容器鏡像,隨後步驟0的中間層則被拋棄,這些中間層不會出現在最終容器鏡像中,從而有效地縮減了最終容器鏡像的尺寸,而這個結果也是從語義上、從邏輯上被自洽的。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"]
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"]
configs
爲每個服務提供具體化的訪問 config
的權限。
一個 config
包含一系列的配置信息,這些信息可能被通過多種途徑所創建。容器的部署引用這些配置時,可以更好地區格諸如生產環境參數這樣的問題。另一方面,敏感信息也因此可以被單獨隔離到一個安全的區域中,在一定程度上減少了泄露的可能性。
NOTE: 指定的配置必須已經存在,或者已經被定義在頂級configs
中了(defined in the top-levelconfigs
configuration)。否則整個容器棧的部署將會失敗。
支持兩個不同的語法變體格式。更詳盡的信息應參考 configs。
短格式
只指定配置名。容器因此可以訪問配置 /<config_name
和掛載它(掛載的源和目標均爲該配置名)。
version: "3.7"
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/UnixUID
和GID
,如果沒有指定則爲0。Windows中不支持。 -
mode
: 8進制的文件權限。默認值爲0444
。配置是不可寫的,因爲它們被掛載於臨時的文件系統中。因此如果你設置了寫許可,這將被忽略。
可執行位是可以被設置的。
下面的例子類似於短格式的例子:
version: "3.7"
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 配置例子
當爲一個服務配置 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.7"
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.7"
services:
redis:
image: redis:alpine
deploy:
replicas: 6
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
幾個子選項是可用的:
endpoint_mode
swarm.
Version 3.3 only.
-
endpoint_mode: vip
- Docker 爲服務請求一個虛擬IP(VIP
)用於訪問。Docker在客戶端和服務的有效的工作節點之間對請求進行自動負載均衡路由。客戶端無需知道服務有多少可用節點,也不必知道服務節點的IP地址和端口號。
這是默認方式。
-
endpoint_mode: dnsrr
- 使用 DNS round-robin (DNSRR) 算法進行服務發現。Docker會爲服務設置一個DNS條目,因而在進行對應的 DNS 解析時通過服務名稱會返回一個IP地址清單。客戶端因此直接選擇一個具體的端點進行訪問。
version: "3.7"
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.7"
services:
web:
image: web
deploy:
labels:
com.example.description: "This label will appear on the web service"
要爲容器設置標籤的話,在 deploy
之外爲服務指定 labels
:
version: "3.7"
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.7"
services:
worker:
image: dockersamples/examplevotingapp_worker
deploy:
mode: global
placement
指定 constaints 和 preferences。
參閱docker服務建立的相關文檔以瞭解更多的關於 constraints 和 [preferences 的相關信息,包括相應的語法,可用的類型等等的完整描述。
version: "3.7"
services:
db:
image: postgres
deploy:
placement:
constraints:
- node.role == manager
- engine.labels.operatingsystem == ubuntu 14.04
preferences:
- spread: node.labels.zone
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.7"
services:
redis:
image: redis:alpine
deploy:
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
以下的主題描述 swarm 場景下的服務或容器資源約束的可用選項。
Out Of Memory Exceptions (OOME)
企圖在你的服務和容器實例中使用超過系統擁有的內存,那麼將得到 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.7"
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
或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.7"
services:
vote:
image: dockersamples/examplevotingapp_vote:before
depends_on:
- redis
deploy:
replicas: 2
update_config:
parallelism: 2
delay: 10s
order: stop-first
NOT SUPPORTED FOR DOCKER STACK DEPLOY
下列的子選項(爲 docker-compose up
和 docker-compose run
所支持)是在 docker stack deploy
中不被支持的:
- build
- cgroup_parent
- container_name
- devices
- tmpfs
- external_links
- links
- network_mode
- restart
- security_opt
- sysctls
- userns_mode
Tip: See the section on how to configure volumes for services, swarms, and docker-stack.yml files. Volumes are supported but to work with swarms and services, they must be configured as named volumes or associated with services that are constrained to nodes with access to the requisite volumes.
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
的值被原樣照用,且不能被修改。例如如果值由引號所包圍,那麼值的表示量中也包含引號。
環境變量文件的順序也需要被注意。位置靠後的環境變量文件中所定義的變量值會覆蓋掉早前定義的舊值。
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: 這些選項在部署一個棧到 swarm mode 時被忽略。
更推薦的做法是通過 networks
構造一個子網以進行容器之間的鏈接。
extra_hosts
添加主機名映射。這些映射關係會被添加到 /etc/hosts
中。此功能等價於命令行參數 --add-host
。
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
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.7"
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"
可用的轉發驅動器可以參考 https://docs.docker.com/confi...。
使用 option
指定驅動器的選項,如同 --log-opt
那樣。例如爲 syslog
這樣指定:
driver: "syslog"
options:
syslog-address: "tcp://192.168.0.42:123"
缺省的日誌轉發驅動爲 json-file
。對此可以指定日誌切割尺寸以及最多保持的日誌歷史文件個數:
version: "3.7"
services:
some-service:
image: some-service
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
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 時被忽略。也參閱 deploying a stack in swarm mode 。
NOTE:
network_mode: "host"
不能和 links 混用。
networks
要加入的網絡。目標網絡是在 docker-compose.yml
頂級的 networks
項中定義的。
services:
some-service:
networks:
- some-network
- other-network
ALIASES
指定網絡中該服務的別名(也即主機名)。相同網絡中別的容器可以使用服務名或者服務別名來連接到該服務的容器實例。
既然 aliases
是網絡範圍內的,同一個服務在不同網絡中可以有不同的別名。
services:
some-service:
networks:
some-network:
aliases:
- alias1
- alias3
other-network:
aliases:
- alias2
一個更復雜而完整的例子:
version: "3.7"
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:
IPV4_ADDRESS, IPV6_ADDRESS
指定一個靜態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.7"
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開始)。
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"
長格式
允許進行冗長的定義:
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.7"
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.7"
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 時被忽略。(此時可以使用 restart_policy
達到目的)
stop_grace_period
指定一個等待時長,如果容器未能攔住 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 時被忽略。(此時可以使用 restart_policy
達到目的)
tmpfs
since v2
掛載一個臨時文件系統到容器中。可以是一個單一值或一個列表。
tmpfs: /run
tmpfs:
- /run
- /tmp
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。(此時可以使用 restart_policy
達到目的)
since v3.6
掛載一個臨時文件系統到容器中。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 時被忽略。(此時可以使用 restart_policy
達到目的)
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.7"
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:
短格式
可以使用 HOST:CONTAINER
格式,或者附帶一個訪問模式 HOST:CONTAINER:ro
。
可以掛載一個主機中的相對路徑。
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.7"
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 之後可用
VOLUMES FOR SERVICES, SWARMS, AND STACK FILES
當工作在 services, swarms, 或 docker-stack.yml
場景下,要注意一個服務在 swarm 中可能被部署到任意節點,而每當服務被更新之後再次啓動時,可能已經不再在原來的節點上了。
當指定名稱的卷並不存在時,Docker會自動創建一個匿名卷用於引用的服務。匿名卷是不可持久化的,因此當關聯的容器實例退出並被移除時,匿名卷也會被銷燬。
如果想要持久化你的數據,採用命名卷以及選擇恰當的卷驅動程序,這個驅動應該是跨主機的,這樣數據才能在不同的主機之間漫遊。否則的話,你應該設置服務的約束條件以便該服務只會被部署到特定的節點上,這些節點上有相應的卷服務在正確工作。
作爲一個例子,votingapp sample in Docker Labs 的 docker-stack.yml
文件定義了 db
服務,運行着 postgresql。它使用了一個命名卷 db-data
來持久化數據庫數據,這個卷被通過swarm約束在只能運行在 manager
這個節點上,因此一切疑難都不存在了。下面是源碼:
version: "3.7"
services:
db:
image: postgres:9.4
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
deploy:
placement:
constraints: [node.role == manager]
CACHING OPTIONS FOR VOLUME MOUNTS (DOCKER DESKTOP FOR MAC)
在 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
指定時間段 duration
有的配置選項,例如 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.7"
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.7"
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.7"
volumes:
data:
name: my-app-data
name
可以被與 external
相組合:
version: "3.7"
volumes:
data:
external: true
name: my-app-data
網絡編排格式手冊 - networks
頂級章節 networks
使得你可以配置想要創建和使用的網絡(Compose內網)。
- 完整的在 Compose 中使用 Docker 網絡環境特性的有關說明,以及所有的網絡驅動程序選項,請參考 Networking guide。
- 對於 Docker Labs 的和網絡相關的輔導用例,請仔細閱讀 Designing Scalable, Portable Docker Container Networks。
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 or 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.7"
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.7"
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.7"
networks:
network1:
name: my-app-net
name
可以與 external
一起連用:
version: "3.7"
networks:
network1:
external: true
name: my-app-net
配置項編排格式手冊 - configs
頂級的 configs
章節聲明,定義了一個配置項或者其參考,該配置項可以被授權給棧內服務使用。配置項的來源可以是 file
或 external
。
-
file
: 配置項的內容在一個宿主機文件中。 -
external
: 如果設置爲true
,表示該配置項已經創建就緒了。Docker將不會試圖建立它,而是在起不存在時生成一個config not found
錯誤。 -
name
: 該配置項在 Docker 中的名字。名字的值可被用於解決具有特殊字符名字的卷。注意該值被原樣使用,引號不會被忽略,也不會被添加上棧名字前綴。
下面的例子中,當作爲棧的一部分被部署時,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 中的名字。名字的值可被用於解決具有特殊字符名字的卷。注意該值被原樣使用,引號不會被忽略,也不會被添加上棧名字前綴。
下面的例子中,當作爲棧的一部分被部署時,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
爲名進行參考和使用。
Compose File v3.5 及更高版本
secrets:
my_first_secret:
file: ./secret_data
my_second_secret:
external: true
name: redis_secret
Compose File v3.4 和更低版本
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
Compose 文檔參考
- User guide
- Installing Compose
- Compose file versions and upgrading
- Get started with Docker
- Samples
- Command line reference