緣起
關於 docker-compose 的安裝,關於 docker 的基本介紹,不在本文的指導範圍內。
這篇文章基本上是 docker-compose YAML 檔案格式的嚴格的英譯中。這麼做,緣起於昨天想起掃描一下 docker-compose 編排中怎麼使用 ${PWD}
的問題,結果中文沒有一點幫助,還是官網最終解決了我的模糊之處。因此我覺得還是應該做一篇比較嚴謹的譯文以及說明,來闡釋 docker-compose 編排的各項細節。
以下,我們主要是介紹 docker-compose 編排檔案格式版本3 的各項細節。
閱讀本文,你應該有 docker-compose 的基本認識,至少有基本的早期(版本2)編排格式的瞭解。
關於授權
譯文從屬於原文 docs.docker.com/compose/com… 。
譯文 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"
複製程式碼
可用的轉發驅動器可以參考 docs.docker.com/config/cont…
使用 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 時被忽略。
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