docker-compose書寫規則

docker-compose書寫規則

本文對集羣部署相關的一概不做介紹

版本約束

Docker Engine >= 19.03
Docker Compose >=3.8

結構介紹

docker-compose.yaml 文件結構主要由

version # docker compose版本
networks # 網絡,用於docker容器內部通訊
x-{name} # 模版命名規則 以x-開頭 用於複用
volumes # 掛載卷
services # 服務模塊,內部定義容器信息 其內部參數相當於docker run時的參數

模塊介紹

Docker Compose官方文檔

version

設定docker-compose.yaml的版本
需要升級的話,參看文檔 版本升級參考文檔

Compose file 版本 Docker Engine 版本
3.8 19.03.0+
3.7 18.06.0+
3.6 18.02.0+
3.5 17.12.0+
3.4 17.09.0+
3.3 17.06.0+
3.2 17.04.0+
3.1 1.13.1+
3.0 1.13.0+
2.4 17.12.0+
2.3 17.06.0+
2.2 1.13.0+
2.1 1.12.0+
2.0 1.10.0+
1.0 1.9.1.+

##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]"

networks

爲當前docker-compose.yaml文件創建的容器設定網絡

不一定存在於和version同級,也可以在各個其他模塊中,例如services中

  • 內部網絡
services:
  some-service:
    networks:
     - some-network
     - other-network
  • 公用網絡
version: "3"
networks:
  default-network:

aliases(待補充)

網絡的別名

version: "3.8"

services:
  web:
    image: "nginx:alpine"
    networks:
      - new

  worker:
    image: "my-worker-image:latest"
    networks:
      - legacy

  db:
    image: mysql
    networks:
      new:
        aliases:
          - database
      legacy:
        aliases:
          - mysql

networks:
  new:
  legacy:

ipv4_address , ipv6_address(待補充)

version: "3.8"

services:
  app:
    image: nginx:alpine
    networks:
      app_net:
        ipv4_address: 172.16.238.10
        ipv6_address: 2001:3984:3989::10

networks:
  app_net:
    ipam:
      driver: default
      config:
        - subnet: "172.16.238.0/24"
        - subnet: "2001:3984:3989::/64"

services

最主要的部分,用來配置各個服務

build

用於構建鏡像,當build和image字段都存在時,使用image指定的鏡像名和tag作爲build鏡像的name和tag

version: "3.8" # docker compose版本
services:
  webapp: # docker-compose定義的服務(容器)名,主要是針對docker-compose命令的參數,與docker ps看到的容器名不一定一致
    build: # 使用Dockerfile構建鏡像
      context: ./dir 上下文路徑,相對路徑則是相對於compose文件路徑
      dockerfile: Dockerfile-alternate # 指定Dockerfile文件名
      args: # 指定Dockerfile的參數 環境變量
        buildno: 1 # directory寫法和list寫法均可

context

可以使用相對路徑或者git倉庫的url

build:
  context: ./dir

Dockerfile

指定Dockerfile文件名,必須指定context

build:
  context: .
  dockerfile: Dockerfile-alternate

args

Dockerfile中的ARG字段,用於指定docker build時的環境變量

ARG buildno
ARG gitcommithash

RUN echo "Build number: $buildno" # bash-like風格的寫法
RUN echo "Based on commit: $gitcommithash"

可以使用list或者map來設定args

build:
  context: .
  args: # map
    buildno: 1
    gitcommithash: cdc3b19
build:
  context: .
  args: # list
    - buildno=1
    - gitcommithash=cdc3b19

tips
如果需要使用boolean值,需要使用雙引號(“true”, “false”, “yes”, “no”, “on”, “off”),以便解析器將他們解析爲字符串。

cache_from

爲build過程指定cache

build:
  context: .
  cache_from:
    - alpine:latest
    - corp/web_app:3.14

labels

同Dockerfile中的LABEL指令,爲鏡像設定metadata

build:
  context: .
  labels: # map
    com.example.description: "Accounting webapp"
    com.example.department: "Finance"
    com.example.label-with-empty-value: ""
build:
  context: .
  labels: # list
    - "com.example.description=Accounting webapp"
    - "com.example.department=Finance"
    - "com.example.label-with-empty-value"

network

docker --network指令,爲容器指定網絡,個人理解爲設定局域網
橋接可以將兩個物理局域網連接起來
三種模式

build:
  context: .
  network: host # host模式,網絡延遲最低,性能與宿主機一致
build:
  context: .
  network: custom_network_1 # 自創network 
build:
  context: .
  network: none # 無網絡

shm_size

設置容器內/dev/shm目錄的大小

/dev/shm目錄非常重要,此目錄並不在硬盤上,而是在內存中,默認大小爲內存的一半大小,存入其中的文件不會被清空,容器內劃分此目錄可以一定程度上指定容器的性能。

build:
  context: .
  shm_size: '2gb' # 使用字符串設置大小
build:
  context: .
  shm_size: 10000000 # 設置字節大小

command

相當於Dockerfile中的CMD命令

command: bundle exec thin -p 3000 # shell-like
command: ["bundle", "exec", "thin", "-p", "3000"] # json-like

container_name

相當於docker run --name

container_name: my-web-container

depends_on

用於表述服務之間的依賴關係

docker-compose up時,會根據depends_on來決定啓動順序

version: "3.8"
services:
  web:
    build: .
    depends_on: # 先啓動 db 和 redis
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

tips:
docker-compose 不會等待depends_on中的容器的狀態時‘ready’時才啓動,所以需要在啓動完成後檢查容器狀態。官方給出瞭解決辦法,使用shell腳本來曲線救國,不做贅述。

depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started. If you need to wait for a service to be ready, see Controlling startup order for more on this problem and strategies for solving it.
       ----form https://docs.docker.com/compose/compose-file/#container_name

devices

掛載的外接設備,與--devices功能相同

devices:
  - "/dev/ttyUSB0:/dev/ttyUSB0"

dns

自定義dns地址

dns: 8.8.8.8 # 單個string值
dns: # list 
  - 8.8.8.8
  - 9.9.9.9

dns_search

自定義dns搜索域名

dns_search: example.com # 單個string值
dns_search:
  - dc1.example.com
  - dc2.example.com

entrypoint

覆蓋重寫默認的 entrypoint

entrypoint: /code/entrypoint.sh

同Dockerfile中的寫法

entrypoint: ["php", "-d", "memory_limit=-1", "vendor/bin/phpunit"]

tips:
docker-compose.yaml 中的 entrypoint 清空Dockerfile中的CMD命令,並覆蓋所有的Dockerfile中的ENTRYPOINT指令。

env_file

docker-compose.yaml添加環境變量文件。如果在docker-compose -f FILE中設置了 compose 文件,則env_file中的文件路徑是相對於FILE的相對路徑

env_file: .env # single value
env_file: # list
  - ./common.env
  - ./apps/web.env
  - /opt/runtime_opts.env

tips:
.env 文件格式:

# Set Rails/Rack environment # '#'爲註釋,
# 空行會被忽略
RACK_ENV=development # 格式爲 VAR=VAL

.env 文件中的環境變量無法在build過程中被顯示讀取,只會被docker-compose.yaml文件讀取,如果需要在build時使用該環境變量,請在build後加args子參數。

對於指定多個.env文件的情況,官網的這句話賊複雜

Keep in mind that the order of files in the list is significant in determining the value assigned to a variable that shows up more than once.
—from https://docs.docker.com/compose/compose-file/#env_file

直譯過來是

請記住,列表中文件的順序對於確定分配給多次顯示的變量的值很重要。

因爲對環境參數文件的處理是自上而下的,所以翻譯成人話就是,多個參數文件中包含同一個環境變量,以最後一個爲準。

environment

添加環境變量

environment: # map
  RACK_ENV: development
  SHOW: 'true'
  SESSION_SECRET:
environment: # list
  - RACK_ENV=development
  - SHOW=true
  - SESSION_SECRET

tips:
.env 文件中的環境變量無法在build過程中被顯示讀取,只會被docker-compose.yaml文件讀取,如果需要在build時使用該環境變量,請在build後加args子參數。
次環境變量在構建鏡像時,可以被我們自身的代碼讀取到,例如:

func getEnvInfo() string {
    rackEnv := os.Getenv("RACK_ENV")
    fmt.Println(rackEnv)
}

output:
development

expose

暴露端口,但是僅限於服務之間的通信,暴露的是內部端口,類似Dockerfile的EXPOSE指令

expose:
  - "3000"
  - "8000"

external_links

連接服務

external_links:
  - redis_1
  - project_db_1:mysql
  - project_db_1:postgresql

tips:
官方推薦使用network

extra_hosts

添加自定義域名,同--add-host

extra_hosts:
  - "somehost:162.242.195.82"
  - "otherhost:50.31.209.229"

也可以在容器內的/etc/hosts文件內寫入

162.242.195.82  somehost
50.31.209.229   otherhost

healthcheck

同Dockerfile中的HEALTHCHECK指令

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"]
  interval: 1m30s
  timeout: 10s
  retries: 3
  start_period: 40s

使用disabel: true,相當於test: ["NONE"]

healthcheck:
  disable: true

image

指定需要拉取或使用的鏡像,也可以使用倉庫/標籤或部分鏡像ID

image: redis # 默認標籤 latest
image: ubuntu:18.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd

init

在容器內運行一個初始化程序,以轉發信號開獲取進程。

version: "3.8"
services:
  web:
    image: alpine:latest
    init: true

tips:
使用的默認初始化二進制文件是Tini,並安裝在/usr/libexec/docker-init守護程序主機上。您可以通過init-path配置選項將守護程序配置爲使用自定義init二進制文件 。

isolation

指定容器隔離技術,Linux只支持default,windows支持default``process hyperv三個值,具體參考 Docker Engine Docs

labels

同Dockerfile中的LABEL指令,爲容器設定metadata

build:
  context: .
  labels: # map
    com.example.description: "Accounting webapp"
    com.example.department: "Finance"
    com.example.label-with-empty-value: ""
build:
  context: .
  labels: # list
    - "com.example.description=Accounting webapp"
    - "com.example.department=Finance"
    - "com.example.label-with-empty-value"

links

舊版的功能,不推薦使用

logging

爲當前服務設置日至參數

logging:
  driver: syslog
  options:
    syslog-address: "tcp://192.168.0.42:123"

driver參數同--log-driver指令

driver: "json-file"
driver: "syslog"
driver: "none"

tips:
只有使用json-filejournald時,docker-compose updocker-compose logs才能看到日誌,其他任何的驅動都無法看到日誌打印。

指定日誌設置,同docker run --log-opt.格式爲k-v結構

driver: "syslog"
options:
  syslog-address: "tcp://192.168.0.42:123"

默認的日誌驅動是json-file,可以設置存儲限制

options:
  max-size: "200k" # 單文件最大存儲
  max-file: "10" # 文件最大數量

tips:
上述的option參數僅爲json-file日誌驅動支持的參數,不同驅動支持的參數各不相同,具體參照下表。

支持的驅動列表

Driver Description
none 不輸出日誌。
local 日誌以自定義格式存儲,旨在最大程度地減少開銷。
json-file 日誌以自定義格式存儲,旨在最大程度地減少開銷。
syslog 將日誌消息寫入syslog設施。該syslog守護程序必須在主機上運行。
journald 將日誌消息寫入journald。該journald守護程序必須在主機上運行。
gelf 將日誌消息寫入Graylog擴展日誌格式(GELF)端點,例如Graylog或Logstash。
fluentd 將日誌消息寫入fluentd(向前輸入)。該fluentd守護程序必須在主機上運行。
awslogs 將日誌消息寫入Amazon CloudWatch Logs。
splunk 將日誌消息寫入到splunk使用HTTP Event Collector。
etwlogs 將日誌消息寫爲Windows事件跟蹤(ETW)事件。僅在Windows平臺上可用。
gcplogs 將日誌消息寫入Google Cloud Platform(GCP)日誌記錄。
logentries 將日誌消息寫入Rapid7 Logentries。

tips:
具體請參考 Configure logging drivers

ports

對外暴露端口

short syntax:
要麼指定兩個端口HOST:CONTAINER,要麼僅指定容器端口(選擇了臨時主機端口)。

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"
  - "12400-12500:1240"

tips:
當以HOST:CONTAINER格式映射端口時,使用低於60的容器端口可能會報錯,因爲YAML會將格式xx:yy中的數字解析爲以60進制的數(可以理解爲時間)。因此建議始終將端口映射顯式指定爲字符串。

long syntax

長語法允許出現短語法不允許出現的字段

  • target:容器內的端口
  • published:公開暴露端口
  • protocol:端口協議(tcp或udp)
  • mode:host用於在每個節點上發佈主機端口,ingress使羣集模式端口達到負載平衡。
ports:
  - target: 80
    published: 8080
    protocol: tcp
    mode: host

restart

容器重啓策略

restart: "no" # 失敗不重啓
restart: always # 失敗後總是重啓
restart: on-failure # 錯誤碼爲 on-failure 時才重啓
restart: unless-stopped # 手動停止後不重啓

secrets(待補充)

volumes

用來掛載數據卷

short syntax
短語法使用最簡單的格式[SOURCE:]TARGET[:MODE]

  • SOURCE可以是宿主機地址,也可以是數據卷名。

  • TARGET是容器內路徑。

  • MODE包括rofor read-onlyrw for read-write(默認)

如果使用宿主機的相對路徑,則以docker-compose.yaml爲基礎進行拓展。

volumes:
  # 指定容器內路徑,docker 自動創建路徑
  - /var/lib/mysql

  # 掛載絕對路徑
  - /opt/data:/var/lib/mysql

  # 掛載相對路徑
  - ./cache:/tmp/cache

  # 用戶目錄相對路徑
  - ~/configs:/etc/configs/:ro

  # 命名掛載
  - datavolume:/var/lib/mysql

long syntax

長語法允許使用短語法無法表達的字段

  • type: 安裝類型, bind, tmpfs 或者 npipe

  • source: 掛載源,可以是宿主機路徑,也可以是頂級掛載設置中設置好的卷名。tmpfs不適用於掛載

  • target: 容器內掛載路徑

  • read_only: 設置掛載路徑只讀

  • bind: 配置額外的綁定設置

    • propagation: 用於設置綁定的傳播模式
  • volume: 配置額外的掛載配置

    • nocopy: 創建卷時禁用從容器複製數據標識位
  • tmpfs: 配置額外的tmpfs配置

    • size: 設置掛載tmpfs的大小(字節)
  • consistency: 裝載的一致性要求,consistent (主機和容器具有相同的視圖),cached(讀緩存,主機視圖具有權威性)或delegated(讀寫緩存,容器的視圖具有權威性)之一

version: "3.8"
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - type: volume
        source: mydata
        target: /data
        volume:
          nocopy: true
      - type: bind
        source: ./static
        target: /opt/app/static

networks:
  webnet:

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