docker-compose 編排指南 (v3.7)

緣起

關於 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:

在這個樣本中,頂級結構由 versionservicesnetworksvolumes 等等標籤構成。這與版本2並沒有什麼翻天覆地的區別。

services 章節中,你可以定義若干個服務,每個服務通常運轉着一個容器,這些服務構成了一個整體的設施棧,又或是服務羣。

一般來說我們會把一堆拉拉雜雜的東西,例如一堆微服務什麼的,編排成一個服務棧,讓他們整體對外服務,從而避免細節外露,也可以加強架構設計彈性和對整個服務棧進行伸縮(而不是面對大批微服務去逐個處理)。

編排格式手冊 - service

接下來會是一個參考手冊應有的章節結構,我們按照字母順序列列舉出了服務編排的指令,例如 portsvolumescmdentry 等等。

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 時被忽略。

也參閱 deploying a stack in swarm mode

Linux 能力機制很大程度上是一種安全機制。具體含義、用途和引申屬於 Linux 操作系統範疇,不再贅述。

cgroup_parent

可選地爲容器指定一個上級 cgroupcgroup 也是 Linux 容器化實現的最重要的基本概念之一。

cgroup_parent: m-executor-abcd
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。

也參閱 deploying a stack in 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-level configs 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_configmy_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 UIDGID,如果沒有指定則爲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 時被忽略。

也參閱 deploying a stack in 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 按照依賴順序依次啓動服務。在下面的例子中,dbredis 先於 web 被啓動。
  • docker-compose up SERVICE 自動包括了 SERVICE 的依賴項。在下面的例子中,docker-compose up web 將會自動啓動 dbredis
  • docker-compose stop 按照依賴順序依次停止服務。在下面的例子中,web 將會被先於 dbredis 被停止。

簡單的示例如下:

version: "3.7"
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

使用 depends_on 時應該注意的幾件事:

  • depends_on 並不意味着等待 dbredis 就緒後才啓動 web,而是在它們被啓動後就會接着啓動 web。如果要想等到服務就緒可用,應該參閱 Controlling startup order
  • 版本 3 不再支持 condition 表述。
  • depends_on 選項在部署到 swarm mode 時被忽略。

也參閱 deploying a stack in swarm mode

deploy

Version 3 only.

指定和部署以及運行相關的配置。

只會對部署到一個使用 docker stack deployswarm 有影響。

docker-compose updocker-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

可以是 globalreplicatedglobal 表示嚴格地一個 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-failureany (默認爲 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: 一個回滾失敗時應當執行的動作。可以是 continuepause(默認爲pause
  • monitor: 失敗的回滾狀態被更新到監視器的週期(ns|us|ms|s|m|h)默認爲 0s
  • max_failure_ratio: 回滾時失敗的可容忍的比例(默認爲0)
  • order: 回滾的操作順序。可以爲 stop-firststart-first(默認爲 stop-first

update_config

指示服務應該如何被更新。這對於配置爲滾動更新時有用:

  • parallelism:同時更新的容器的數量值。如果設置爲0,所有容器將被同時回滾。
  • delay: 每個容器組被更新前的等待時長(默認爲0)
  • failure_action: 一個更新失敗時應當執行的動作。可以是 continuepause(默認爲pause
  • monitor: 失敗的更新狀態被更新到監視器的週期(ns|us|ms|s|m|h)默認爲 0s
  • max_failure_ratio: 更新時失敗的可容忍的比例(默認爲0)
  • order: 更新的操作順序。可以爲 stop-firststart-first(默認爲 stop-first
NOTEorder 只在 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 updocker-compose run 所支持)是在 docker stack deploy 中不被支持的:

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 時被忽略。

也參閱 deploying a stack in 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 時被忽略。

也參閱 deploying a stack in 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, timeoutstart_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, processhyperv

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 達到目的)

也參閱 deploying a stack in swarm mode

secrets

從每個服務配置中,授權訪問頂級 secrets 定義的表項。支持長短兩個格式。

短格式

短格式僅指定敏感內容的名字。這使得容器能夠掛載對應內容到 /run/secrets/<secret_name> 位置並訪問它。

下面的例子使用短格式,讓 redis 能夠訪問 my_secretmy_other_secretmy_secret 的具體內容被定義在 ./my_secret.txtmy_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 達到目的)

也參閱 deploying a stack in swarm mode

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 達到目的)

也參閱 deploying a stack in swarm mode

tmpfs

since v2

掛載一個臨時文件系統到容器中。可以是一個單一值或一個列表。

tmpfs: /run
tmpfs:
  - /run
  - /tmp
NOTE: 這些選項在部署一個棧到 swarm mode 時被忽略。(此時可以使用 restart_policy 達到目的)

也參閱 deploying a stack in swarm mode

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 達到目的)

也參閱 deploying a stack in 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.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, tmpfsnpipe
  • 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 Labsdocker-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, mg。此外,kb, mbgb 也是合法的。純粹的十進制數值並不合法。

卷編排格式手冊 - volumes

頂級的 volumes 章節可以聲明和創建命名卷(無需使用 volume_from),這些卷能夠被用於在 service 章節下的 volumes 小節中被引用。所以我們可以重用它們,甚至能夠跨越多個 services。docker命令的 docker volume 子命令有更多的參考信息。

關於卷的使用,也可以參考 Use volumesVolume 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內網)。

driver

指定該網絡的驅動程序。

缺省的驅動程序由 Docker Engine 的啓動參數所指定。通常情況下,啓動參數內置爲在單節點宿主機上使用 bridge 驅動,而在 swarm mode 中使用 overlay 驅動。

如果驅動程序不可用,Docker Engine 將會返回一個錯誤。

driver: overlay

bridge

缺省時 Docker 在每個宿主機節點上使用 bridge 驅動。有關橋接網絡是如何工作的,可以參考 Docker Labs 的和網絡相關的輔導用例:Bridge networking

overlay

overlay 驅動在多個 swarm mode 節點之間建立一個命名子網,這是一個跨主機的虛擬網絡。

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.

使用內建的網絡模型,例如 hostnone,語法上有一點點需要注意的地方:如果用 hostnone 這樣的名字定義一個外部網絡(注意你並不需要真的創建他們,這兩者都屬於Docker內置的網絡模型),那麼在 Compose 編排文件中引用它們時你需要使用 hostnetnonet,如同這樣:

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 章節聲明,定義了一個配置項或者其參考,該配置項可以被授權給棧內服務使用。配置項的來源可以是 fileexternal

  • 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 章節聲明,定義了一個敏感信息項或者其參考,該敏感信息項可以被授權給棧內服務使用。敏感信息項的來源可以是 fileexternal

  • 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 文檔參考

結束

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章