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

hedzr發表於2019-09-10

緣起

關於 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:
複製程式碼

在這個樣本中,頂級結構由 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"
複製程式碼

可用的轉發驅動器可以參考 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 時被忽略。

也參閱 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 文件參考

結束

相關文章