簡介
Compose 是用于定義和運行多容器 Docker 應用程序的工具。通過 Compose,您可以使用 YML 文件來配置應用程序需要的所有服務。然后,使用一個命令,就可以從 YML 文件配置中創建并啟動所有服務。
docker compose文件是一個yaml格式的文件,所以注意行首的縮進很嚴格,docker compose文件的格式很不同版本,版本不同,語法和格式有所不同
默認docker-compose命令會調用當前目錄下的docker-compose.yml的文件,因此一般執行docker-compose命令前先進入docker-compose.yml文件所在目錄
- Compose 使用的三個步驟:
1.使用 Dockerfile 定義應用程序的環境。
2.使用 docker-compose.yml 定義構成應用程序的服務,這樣它們可以在隔離環境中一起運行。
3.執行 docker-compose up 命令來啟動并運行整個應用程序。
https://zhuanlan.zhihu.com/p/387840381
compose 的諸多優點:
-
- 在單個主機上建立多個隔離環境,Compose 使用項目名稱將環境彼此隔離。您可以在多個不同的上下文中使用此項目名稱。默認項目名稱是項目目錄的基本名稱。您可以使用-p 命令行選項或 COMPOSE_PROJECT_NAME 環境變量設置自定義項目名稱 。默認項目目錄是 Compose 文件的基本目錄。可以使用--project-directory 命令行選項自定義項目目錄。
- 創建容器時保留卷數據
- 僅重新創建已更改的容器,當您重新啟動未更改的服務時,Compose 會使用現有容器。
- 變量在環境之間組合重復使用
多個配置文件
我們可以為同一個項目配置多個compose文件,使用多個 Compose 文件使您能夠針對不同的環境或不同的工作流程自定義 Compose 應用程序。
默認情況下,Compose 讀取兩個文件,docker-compose.yml和一個可選的
docker-compose.override.yml文件。按照慣例,docker-compose.yml包含您的基本配置。override.yml 文件,顧名思義,就是包含現有服務或全新服務的配置覆蓋。
如果在兩個文件中都定義了服務,Compose 會使用 override 進行合并配置。
要使用多個覆蓋文件或具有不同名稱的覆蓋文件,您可以使用該-f選項來指定文件列表。Compose 按照在命令行中指定的順序合并文件。
當您使用多個配置文件時,您必須確保文件中的所有路徑都相對于基本 Compose 文件( 指定的第一個 Compose 文件-f)。
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
docker-compose.yml完整選項樣式
version: "3.7"
services:#部署的項目名稱,容器名稱如果沒有定,此項會變成容器名并添加 _1.nginx_config_web: #鏡像名稱地址image: docker.com/nginx:app1#指定容器名稱,由于容器名稱是唯一的,如果指定自定義名稱,則無法scalecontainer_name: my-nginx-container#容器主機名hostname: nginx-server#執行命令,覆蓋默認命令command: bundle exec thin -p 3000# orcommand: ["bundle", "exec", "thin", "-p", "3000"]#重啟策略,默認no,always,no-failure,unless-stoped ,在 swarm 使用 restart_policy 代替 restart)restart: always# 添加環境變量。您可以使用數組或字典、任何布爾值,布爾值需要用引號引起來,# 以確保 YML 解析器不會將其轉換為 True 或 False。environment:- TZ=Asia/Shanghai- SHOW: 'true'#暴露容器端口,與-p相同,但不能低于60,映射到宿主機。 ports:- 80:80- 443:443#暴露端口,但不映射到宿主機,只被連接的服務訪問。與 Dockerfile 中的 EXPOSE 指令一樣,用于指定暴露的端口,僅可以指定內部端口為參數:,實際上 docker-compose.yml 的端口映射還得 ports 這樣的標簽expose:- "3000"- "8000”# 設置容器DNS,可以是單個值或列表。dns: 8.8.8.8dns:- 8.8.8.8- 9.9.9.9# 自定義 DNS 搜索域。可以是單個值或列表。dns_search:dc1.example.comdns_search:- dc1.example.com- dc2.example.com# 掛載宿主機路徑或命令卷 volumes:- ./conf.d:/etc/nginx/conf.d- ./logs:/var/log/nginx- ./ssl:/ssl_certs# 從其它容器或者服務掛載數據卷,可選的參數是:ro或 :rw,前者表示容器只讀,后者表示容器對數據卷是可讀可寫的(默認情況為可讀可寫的)。volumes_from:- service_name- service_name:ro- container:container_name- container:container_name:rw#設置依賴關系。depends_on:- db- redis# 服務的日志記錄配置。logging:driver: json-fileoptions:max-size: "200k" max-file: "10" # 用于檢測 docker 服務是否健康運行。healthcheck:disable: truetest: ["CMD", "curl", "-f", "http://localhost"] # interval: 1m30s timeout: 10s retries: 3 start_period: 40s # 添加或刪除容器擁有的宿主機的內核功能,ALL # 開啟或關閉全部權限cap_add:- SYS_PTRACEcap_drop:- NET_ADMIN- SYS_PTRACE # sysctls設置容器中的內核參數,可以使用數組或字典格式。sysctls:net.core.somaxconn: 1024net.ipv4.tcp_syncookies: 0# 為容器指定父 cgroup 組,意味著將繼承該組的資源限制。cgroup_parent: m-executor-abcd# 在 Dockerfile 中有一個指令叫做 ENTRYPOINT 指令,用于指定接入點。# 在 docker-compose.yml 中可以定義接入點,覆蓋 Dockerfile 中的定義:# 單個值:(entrypoint: /code/entrypoint.sh)entrypoint:- php- -d- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so# 從文件添加環境變量。可以是單個值(env_file: .env)或列表的多個值。env_file:- ./tomcat/config/env# 指定設備映射列表。devices:- "/dev/ttyUSB0:/dev/ttyUSB0"# 鏈接到 docker-compose.yml 外部的容器,甚至 并非 Compose 項目文件管理的容器。參數格式跟 links 類似# 在使用Docker過程中,會有許多單獨使用 docker run 啟動的容器的情況,# 為了使 Compose 能夠連接這些不在docker-compose.yml 配置文件中定義的容器,# 那么就需要一個特殊的標簽,就是 external_links,# 它可以讓Compose 項目里面的容器連接到那些項目配置外部的容器# (前提是外部容器中必須至少有一個容器是連接到與項目內的服務的同一個網絡里面)。external_links:- redis_1- project_db_1:mysql- project_db_1:postgresql# 鏈接到其它服務的中的容器,可以指定服務名稱也可以指定鏈接別名(SERVICE:ALIAS),# 與 Docker 客戶端的 --link 有一樣效果,會連接到其它服務中的容器, # 使用的別名將會自動在服務容器中的 /etc/hosts 里創建links:- db:database- redis# 添加主機名映射。類似 docker客戶端中的 --add-host。# 以上會在此服務的內部容器中 /etc/hosts 創建一個具有 ip 地址和主機名的映射關系:extra_hosts:- "somehost:162.242.195.82"# 網絡模式,用法類似于 Docke 客戶端的 --net 選項,格式為:service:[service name]# 可以指定使用服務或者容器的網絡network_mode: “bridge”network_mode: “host”network_mode: “none”network_mode: “service:[service name]”network_mode: “container:[container name/id]”# 存儲敏感數據,例如密碼:secrets- my_user_scerets #調用密碼文件# 加入指定網絡,下面定義的網絡networks: - front-tier- back-tier# 定義的網絡,與 services字段同級 如:nginx mysql 。
networks:front-tier:driver: bridgeback-tier:driver: bridge# 定義密碼, 與 services下的字段項目同級
secrets:my_secret:file: ./my_secret.txt
docker-compose.yml 配選項說明
version
版本信息,定義關乎于docker的兼容性,Compose 文件格式有3個版本,分別為1,?2.x?和?3.x
build
服務除了可以基于指定的鏡像,還可以基于一份?Dockerfile,在使用 up 啟動之時執行構建任務,這個構建標簽就是 build,它可以指定 Dockerfile 所在文件夾的路徑。Compose?將會利用它自動構建這個鏡像,然后使用這個鏡像啟動服務容器。
例如?webapp?服務,指定為從上下文路徑?./dir/Dockerfile?所構建的鏡像:
version: "3.7"
services:webapp:build: ./dir #可以使用絕對路徑
或者,作為具有在上下文指定的路徑的對象,以及可選的 Dockerfile 和 args:
version: "3.7"
services:webapp:build:context: ./dirdockerfile: Dockerfile-alternateargs:buildno: 1labels:- "com.example.description=Accounting webapp"- "com.example.department=Finance"- "com.example.label-with-empty-value"target: prod
context:
如果?context?中有指定的路徑,并且可以選定?Dockerfile?和?args。那么?arg?這個標簽,就像?Dockerfile?中的?ARG?指令,它可以在構建過程中指定環境變量,
但是在構建成功后取消,在?docker-compose.yml?文件中也支持這樣的寫法。
-
- context?上下文路徑,可以是文件路徑,也可以是到鏈接到 git 倉庫的 url。當是相對路徑時,它被解釋為相對于 Compose 文件的位置。
- dockerfile:指定構建鏡像的 Dockerfile 文件名。
- args:構建參數,只能在構建過程中訪問的環境變量。
- labels:設置構建鏡像的標簽。
- target:多層構建,可以指定構建哪一層。
- cache_from:緩存解析鏡像列表
- labels: 設置構建鏡像的元數據
- network: 設置網絡容器連接,none 表示在構建期間禁用網絡
- shm_size: 設置/dev/shm此構建容器的分區大小
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 之前停止。
注意:web 服務不會等待 redis db 完全啟動 之后才啟動。
version: "3.7"
services:web:build: .depends_on:- db- redisredis:image: redisdb:image: postgres
deploy
指定與服務的部署和運行有關的配置。只在 swarm 模式下才會有用。
deploy配置詳解
只在 swarm 模式下才會有用。
deploy: # v3 版本以上, 指定與部署和運行服務相關的配置, deploy 部分是 docker stack 使用的, docker stack 依賴 docker swarmendpoint_mode: # v3.3 版本中新增的功能, 指定服務暴露的方式vip # Docker 為該服務分配了一個虛擬 IP(VIP), 作為客戶端的訪問服務的地址dnsrr # DNS輪詢, Docker 為該服務設置 DNS 條目, 使得服務名稱的 DNS 查詢返回一個 IP 地址列表, 客戶端直接訪問其中的一個地址labels: # 指定服務的標簽,這些標簽僅在服務上設置mode: # 指定 deploy 的模式global # 每個集群節點都只有一個容器replicated # 用戶可以指定集群中容器的數量(默認)placement: # 指定約束和首選項的位置replicas: # deploy 的 mode 為 replicated 時, 指定容器副本的數量resources: # 資源限制limits: # 設置容器的資源限制cpus: "0.5" # 設置該容器最多只能使用 50% 的 CPU memory: 50M # 設置該容器最多只能使用 50M 的內存空間 reservations: # 設置為容器預留的系統資源(隨時可用)cpus: "0.2" # 為該容器保留 20% 的 CPUmemory: 20M # 為該容器保留 20M 的內存空間restart_policy: # 定義容器重啟策略, 用于代替 restart 參數condition: # 定義容器重啟策略(接受三個參數)none # 不嘗試重啟on-failure # 只有當容器內部應用程序出現問題才會重啟any # 無論如何都會嘗試重啟(默認)delay: # 嘗試重啟的間隔時間(默認為 0s)max_attempts: # 嘗試重啟次數(默認一直嘗試重啟)window: # 檢查重啟是否成功之前的等待時間(即如果容器啟動了, 隔多少秒之后去檢測容器是否正常, 默認 0s)update_config: # 用于配置滾動更新配置parallelism: # 一次性更新的容器數量delay: # 更新一組容器之間的間隔時間failure_action: # 定義更新失敗的策略continue # 繼續更新rollback # 回滾更新pause # 暫停更新(默認)monitor: # 每次更新后的持續時間以監視更新是否失敗(單位: ns|us|ms|s|m|h) (默認為0)max_failure_ratio # 回滾期間容忍的失敗率(默認值為0)order: # v3.4 版本中新增的參數, 回滾期間的操作順序stop-first #舊任務在啟動新任務之前停止(默認)start-first #首先啟動新任務, 并且正在運行的任務暫時重疊rollback_config: # v3.7 版本中新增的參數, 用于定義在 update_config 更新失敗的回滾策略parallelism: # 一次回滾的容器數, 如果設置為0, 則所有容器同時回滾delay: # 每個組回滾之間的時間間隔(默認為0)failure_action: # 定義回滾失敗的策略continue # 繼續回滾pause # 暫停回滾monitor: # 每次回滾任務后的持續時間以監視失敗(單位: ns|us|ms|s|m|h) (默認為0)max_failure_ratio: # 回滾期間容忍的失敗率(默認值0)order: # 回滾期間的操作順序stop-first # 舊任務在啟動新任務之前停止(默認)start-first # 首先啟動新任務, 并且正在運行的任務暫時重疊
可以選參數:
-
- endpoint_mode:訪問集群服務的方式。
- vip?endpoint_mode: vip,?Docker 集群服務一個對外的虛擬 ip。所有的請求都會通過這個虛擬 ip 到達集群服務內部的機器。
- dnsrr?endpoint_mode: dnsrr,?DNS 輪詢(DNSRR)。所有的請求會自動輪詢獲取到集群 ip 列表中的一個 ip 地址。
- labels:在服務上設置標簽。可以用容器上的 labels(跟 deploy 同級的配置) 覆蓋 deploy 下的 labels。
- mode:指定服務提供的模式。
- replicated:復制服務,復制指定服務到集群的機器上。
- global: 全局服務,服務將部署至集群的每個節點。
- replicas:mode?為?replicated?時,需要使用此參數配置具體運行的節點數量。
- resources:配置服務器資源使用的限制,在下面示例中,redis服務被限制為使用不超過?50M?的內存和0.50(單核的?50%)可用處理時間 (CPU),并保留20M內存和0.25CPU 時間(始終可用)。
- endpoint_mode:訪問集群服務的方式。
version: "3.9"
services:redis:image: redis:alpinedeploy:resources:limits:cpus: '0.50'memory: 50Mreservations:cpus: '0.25'memory: 20M
-
- restart_policy:配置是否以及如何在退出時重新啟動容器。替換restart。
- condition: none, on-failure 或 any (默認: any) 之一。
- delay:重新啟動嘗試之間等待的時間(默認值:5s)。
- max_attempts:在放棄之前嘗試重新啟動容器的次數(默認值:永不放棄)。如果在配置的窗口(window)內重新啟動未成功,則此嘗試不計入配置max_attempts值。例如,如果 max_attempts 設置為“2”,并且第一次嘗試重啟失敗,則可能會嘗試兩次以上的重啟。
- window:在決定重啟是否成功之前等待多長時間(默認值:立即重啟)。
- condition:可選 none,on-failure 或者 any(默認值:any)。
- delay:設置多久之后重啟(默認值:0)。
- max_attempts:嘗試重新啟動容器的次數,超出次數,則不再嘗試(默認值:一直重試)。
- window:設置容器重啟超時時間(默認值:0)。
- rollback_config:配置在更新失敗的情況下應如何回滾服務。
- parallelism:一次回滾的容器數量。如果設置為 0,則所有容器同時回滾。
- delay:每個容器組回滾之間等待的時間(默認為 0 秒)。
- failure_action: 如果回滾失敗怎么辦。continue或者pause(默認pause)
- monitor:每次任務更新后監控失敗的持續時間(ns|us|ms|s|m|h)(默認 5s)注意:設置為 0 將使用默認 5s。
- max_failure_ratio:回滾期間允許的故障率(默認為 0)。
- order:回滾期間的操作順序。stop-first(舊任務在開始新任務之前停止),或start-first(首先啟動新任務,并且正在運行的任務短暫重疊)(默認stop-first)。
- max_replicas_per_node:?如果服務是replicated(默認值),則限制任何時間在節點上運行的副本數
- update_config:配置應如何更新服務,對于配置滾動更新很有用。
- parallelism:一次更新的容器數。
- delay:在更新一組容器之間等待的時間。
- failure_action:如果更新失敗,該怎么辦。其中一個 continue,rollback 或者pause (默認:pause)。
- monitor:每個容器更新后,持續觀察是否失敗了的時間 (ns|us|ms|s|m|h)(默認為0s)。
- max_failure_ratio:更新期間可容忍的故障率。
- order:回滾期間的操作順序。其中一個 stop-first(串行回滾),或者 start-first(并行回滾)(默認stop-first)。
注:僅支持 V3.4 及更高版本。
-
- placement
placement?指定約束和首選項的位置。
version: "3.9"
services:db:image: postgresdeploy:placement:constraints:- "node.role==manager"- "engine.labels.operatingsystem==ubuntu 18.04"preferences:- spread: node.labels.zone
您可以通過定義約束表達式來限制可以安排任務的節點集。約束表達式可以使用匹配(==) 或排除(!=) 規則。多個約束查找可以使用 AND 匹配。約束可以匹配節點或 Docker 引擎標簽,如下所示:
節點屬性 | 匹配 | 例子 |
node.id | 節點 ID | node.id==2ivku8v2gvtg4 |
node.hostname | 節點主機名 | node.hostname!=node-2 |
node.role | 節點角色 ( manager/ worker) | node.role==manager |
node.platform.os | 節點操作系統 | node.platform.os==windows |
node.platform.arch | 節點架構 | node.platform.arch==x86_64 |
node.labels | 用戶定義的節點標簽 | node.labels.security==high |
engine.labels | Docker 引擎的標簽 | engine.labels.operatingsystem==ubuntu-14.04 |
restart
定義容器重啟策略
- no:默認的重啟策略,在任何情況下都不會重啟容器。
- always:容器總是重新啟動。
- on-failure:在容器非正常退出時(退出狀態非0),才會重啟容器。
- unless-stopped:在容器退出時總是重啟容器,但是不考慮在Docker守護進程啟動時就已經停止了的容器
注:swarm?集群模式,請改用?restart_policy代替?restart。
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
networks
networks下的條目
默認情況下,Compose為您的應用程序設置單個網絡。services?服務的每個容器都加入默認網絡,并且可以被該網絡上的其他容器訪問。
您的應用程序網絡的名稱基于“項目名稱”,也就是其所在目錄的名稱。您可以使用 --project-name 命令行選項 或?COMPOSE_PROJECT_NAME?環境變量覆蓋項目名稱。
簡單示例
例如,假設您的應用程序是在一個名為myapp目錄下,docker-compose.yml如下:
version: "3.9"
services:web:build: .ports:- "8000:8000"db:image: postgresports:- "8001:5432"
運行docker-compose up,會發生以下情況:
- 創建了一個名為 myapp_default 的網絡。
- 把web加入網絡。
- 把db加入網絡。
上面例子還有一個注意點就是端口號,注意區分HOST_PORT和CONTAINER_PORT,以上面的db為例:
- 8001?是宿主機的端口
- 5432(postgres的默認端口) 是容器的端口
當容器之間通訊時 , 是通過?CONTAINER_PORT?來連接的。
networks配置容器連接的網絡,引用頂級?networks?下的條目 。
networks: # 定義 networks 信息driver: # 指定網絡模式, 大多數情況下, 它 bridge 于單個主機和 overlay Swarm 上bridge # Docker 默認使用 bridge 連接單個主機上的網絡overlay # overlay 驅動程序創建一個跨多個節點命名的網絡群host # 共享主機網絡名稱空間(等同于 docker run --net=host)none # 等同于 docker run --net=nonedriver_opts: # v3.2以上版本, 傳遞給驅動程序的參數, 這些參數取決于驅動程序attachable: # driver 為 overlay 時使用, 如果設置為 true 則除了服務之外,獨立容器也可以附加到該網絡; 如果獨立容器連接到該網絡,則它可以與其他 Docker 守護進程連接到的該網絡的服務和獨立容器進行通信ipam: # 自定義 IPAM 配置. 這是一個具有多個屬性的對象, 每個屬性都是可選的driver: bridge/default # IPAM 驅動程序, bridge 或者 defaultconfig: # 配置項- subnet: # CIDR格式的子網,表示該網絡的網段external: true/false # 外部網絡, 如果設置為 true 則 docker-compose up 不會嘗試創建它, 如果它不存在則引發錯誤name: # v3.5 以上版本, 為此網絡設置名稱aliases: {aliases_name} # 同一網絡上的其他容器可以使用服務名稱或此別名來連接到對應容器的服務。
默認情況下,Compose為您的應用程序設置單個網絡。services?服務的每個容器都加入默認網絡,并且可以被該網絡上的其他容器訪問。
您的應用程序網絡的名稱基于“項目名稱”,也就是其所在目錄的名稱。
您可以使用?--project-name?命令行選項 或?COMPOSE_PROJECT_NAME?環境變量覆蓋項目名稱。
例如,假設您的應用程序是在一個名為myapp目錄下,docker-compose.yml如下:
version: "3.9"
services:web:build: .ports:- "8000:8000"db:image: postgresports:- "8001:5432"
運行docker-compose up,會發生以下情況:
- 創建了一個名為?myapp_default?的網絡。
- 把web加入網絡。
- 把db加入網絡。
上面例子還有一個注意點就是端口號,注意區分HOST_PORT和CONTAINER_PORT,以上面的db為例:
我們可以通過設置一級配置network自定義網絡,創建更復雜的網絡選項,也可以用來連接已經存在的網絡(不是通過compose創建的)
設置一級配置network自定義網絡
我們可以通過設置一級配置network自定義網絡,創建更復雜的網絡選項,也可以用來連接已經存在的網絡(不是通過compose創建的)
每個service 配置下也可以指定networks配置,來指定一級配置的網絡。
version: "3"
services:proxy:build: ./proxynetworks:- frontendapp:build: ./appnetworks:- frontend- backenddb:image: postgresnetworks:- backend
networks:frontend:# 使用自定義驅動程序driver: custom-driver-1backend:# 使用具有特殊選項的自定義驅動程序driver: custom-driver-2driver_opts:foo: "1"bar: "2"
一級配置networks?創建了自定義的網絡 。這里配置了兩個frontend和backend?,且自定義了網絡類型。
每一個services下,proxy?,?app?,?db都定義了networks配置。
- proxy 只加入到 frontend網絡。
- db 只加入到backend網絡。
- app同時加入到 frontend和backend 。
- db和proxy不能通訊,因為不在一個網絡中。
- app和兩個都能通訊,因為app在兩個網絡中都有配置。
- db和proxy要通訊,只能通過app這個應用來連接。
服務之間的訪問
同一網絡上的其他容器可以使用服務名稱或別名來連接到其他服務的容器。
services:some-service:networks:some-network:aliases:- alias1- alias3other-network:aliases:- alias2
指定容器靜態 IP 地址
加入網絡時,還可以指定容器的靜態 IP 地址。
version: "3.9"
services:app:image: nginx:alpinenetworks:app_net:ipv4_address: 172.16.238.10 #IP地址ipv6_address: 2001:3984:3989::10
networks:app_net:ipam:driver: defaultconfig:- subnet: "172.16.238.0/24" #地址范圍- subnet: "2001:3984:3989::/64"
一級networks的其它配置
一級networks還有如下這些配置:
driver
指定該網絡應使用哪個驅動程序。默認使用bridge單個主機上的網絡,overlay代表跨多個節點的網絡群
driver: overlay
driver_opts
將選項列表指定為鍵值對以傳遞給此網絡的驅動程序
driver_opts:foo: "bar"baz: 1
attachable
attachable?僅在driver設置為?overlay時可用。如果設置為true,那么除了服務之外,獨立容器也可以連接到此網絡。
networks:mynet1:driver: overlayattachable: true
enable_ipv6
enable_ipv6 在此網絡上啟用 IPv6 網絡。
ipam
ipam 自定義 IPAM (IP地址管理)配置。
ipam:driver: defaultconfig:- subnet: 172.28.0.0/16
internal
internal 默認情況下,Docker 會將橋接網絡連接到它提供外部連接。如果要創建外部隔離的覆蓋網絡,可以將此選項設置為true。
labels
labels 添加元數據
external
external如果設置為true,則指定此網絡是在 Compose 之外創建的。docker-compose up不會嘗試創建它,如果它不存在,則會引發錯誤。在下面的例子中,proxy是通往外界的門戶。
version: "3.9"
services:proxy:build: ./proxynetworks:- outside- defaultapp:build: ./appnetworks:- default
networks:outside:external: true
name
name為此網絡設置自定義名稱。
version: "3.9"
networks:network1:name: my-app-net
configs
為每個服務賦予相應的訪問權限,支持兩種不同的語法:簡單語法和復雜語法
Note: 配置必須存在或在 configs 此堆棧文件的頂層中定義,否則堆棧部署失效
SHORT語法
指定配置名稱即可。
SHORT?語法只能指定配置名稱,這允許容器訪問配置并將其安裝在 /<config_name> 容器內,源名稱和目標裝入點都設為配置名稱。
Note: config 定義僅在 3.3 版本或在更高版本的撰寫文件格式中受支持,YAML 的布爾值(true, false, yes, no, on, off)必須要使用引號引起來(單引號、雙引號均可),否則會當成字符串解析。
以下實例使用 SHORT 語法將 redis 服務訪問授予?my_config?和?my_other_config的權限?,并被?my_other_config?定義為外部資源,這意味著它已經在 Docker 中定義。可以通過 docker config create 命令或通過另一個堆棧部署。如果外部部署配置都不存在,則堆棧部署會失敗并出現 config not found 錯誤。
version: "3.9"
services:redis:image: redis:latestdeploy:replicas: 1configs:- my_config- my_other_config
configs:my_config:file: ./my_config.txtmy_other_config:external: true
LONG 語法
LONG 語法提供了創建服務配置的更加詳細的信息
-
- source: 配置名稱
- target:要掛載文件的路徑和名稱, 如果未指定則默認為 /
- uid?和?gid: 在服務的任務容器中擁有安裝的配置文件的數字 UID 或 GID。如果未指定,則默認為在Linux上。Windows不支持。
- mode: 在服務的任務容器中安裝的文件的權限,以八進制表示法。例如,0444 代表文件可讀的。默認是 0444。如果配置文件無法寫入,是因為它們安裝在臨時文件系統中,所以如果設置了可寫位,它將被忽略。可執行位可以設置。如果您不熟悉 UNIX 文件權限模式,Unix Permissions Calculator
下面示例在容器中將?my_config?名稱設置為?redis_config,將模式設置為?0440(group-readable)并將用戶和組設置為 103。該redis服務無法訪問?my_other_config?配置。
version: "3.9"
services:redis:image: redis:latestdeploy:replicas: 1configs:- source: my_configtarget: /redis_configuid: '103'gid: '103'mode: 0440
configs:my_config:file: ./my_config.txtmy_other_config:external: true
可以同時授予多個配置的服務相應的訪問權限,也可以混合使用 LONG 和 SHORT 語法。定義配置并不意味著授予服務訪問權限
一級configs詳細配置:
-
- file: 使用指定路徑中的文件內容創建配置。
- external: 如果設置為 true,則指定此配置已經創建。Docker 不會嘗試創建它,如果它不存在, 會報錯config not found。
- name: Docker 中配置對象的名稱。此字段可用于引用包含特殊字符的配置。
- driver和driver_opts:自定義驅動程序的名稱,以及作為鍵/值對傳遞的特定于驅動程序的選項。
- template_driver:要使用的模板驅動程序的名稱,它控制是否以及如何將配置負載作為模板。如果未設置驅動程序,則不使用模板。當前支持的唯一驅動程序是golang,它使用golang。
在下面例子中,my_first_config是通過confif_data文件內容創建的(就像 <stack_name>_my_first_config)部署堆棧時一樣,并且my_second_config已經創建過。
configs:my_first_config:file: ./config_datamy_second_config:external: true
當 Docker 中的配置名稱與服務中存在的名稱不同時,可以使用name進行配置。
configs:my_first_config:file: ./config_datamy_second_config:external:name: redis_config
cap_add, cap_drop
添加或刪除容器功能。
cap_add:- ALLcap_drop:- NET_ADMIN- SYS_ADMIN
cgroup_parent
為容器指定一個可選的父 cgroup。
cgroup_parent: m-executor-abcd
command
覆蓋容器啟動后默認執行的命令
command: bundle exec thin -p 3000
command: ["bundle", "exec", "thin", "-p", "3000"]
container_name
指定自定義容器名稱,而不是生成的默認名稱。由于 Docker 容器名稱必須是唯一的,因此如果您指定了自定義名稱,則不能將服務擴展到 1 個以上的容器。
credential_spec
為托管服務帳戶配置憑據規范。此選項僅用于使用 Windows 容器的服務。在credential_spec上的配置列表格式為file://<filename>或registry://<value-name>
devices
設備映射列表。使用與--devicedocker 客戶端創建選項格式相同。
devices:- "/dev/ttyUSB0:/dev/ttyUSB0"
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指令,用于運行程序。在docker-compose.yml中可以定義覆蓋?Dockerfile?中定義的?entrypoint:
entrypoint: /code/entrypoint.sh
entrypoint: ["php", "-d", "memory_limit=-1", "vendor/bin/phpunit"]
env_file
從文件添加環境變量。可以是單個值或列表。
如果您使用指定了?Compose?文件docker-compose -f FILE,則其中的路徑?env_file相對于該文件所在的目錄。
environment?聲明的環境變量會覆蓋這些值——即使這些值是空的或未定義的。
env_file: .env
env_file:- ./common.env- ./apps/web.env- /opt/runtime_opts.env
environment
添加環境變量。您可以使用數組或字典。任何布爾值(true、false、yes、no)都需要用引號括起來,以確保它們不會被 YML 解析器轉換為?True?或?False。
一般 arg 標簽的變量僅用在構建過程中。而environment和 Dockerfile 中的ENV指令一樣會把變量一直保存在鏡像、容器中,類似docker run -e的效果
environment:RACK_ENV: developmentSHOW: 'true'SESSION_SECRET:environment:- RACK_ENV=development- SHOW=true- SESSION_SECRET
expose
暴露端口,但不映射到宿主機,只被連接的服務訪問。這個標簽與?Dockerfile?中的EXPOSE指令一樣,用于指定暴露的端口,但是只是作為一種參考,實際上docker-compose.yml的端口映射還得ports這樣的標簽。
external_links
鏈接到 docker-compose.yml 外部的容器,甚至 并非?Compose?項目文件管理的容器。
external_links:- redis_1- project_db_1:mysql- project_db_1:postgresql
extra_hosts
添加主機名映射。使用與 docker 客戶端--add-host類似。
extra_hosts:- "somehost:162.242.195.82"- "otherhost:50.31.209.229"
會往/etc/hosts文件中添加一些記錄,啟動之后查看容器內部?hosts可以看到:
162.242.195.82 somehost
50.31.209.229 otherhost
healthcheck
配置運行的檢查以確定此服務的容器是否“健康”。
healthcheck:test: ["CMD", "curl", "-f", "http://localhost"] # 設置檢測程序interval: 1m30s # 設置檢測間隔timeout: 10s # 設置檢測超時時間retries: 3 # 設置重試次數start_period: 40s # 啟動后,多少秒開始啟動檢測程序
interval,timeout?和?start_period都是持續時間。test必須是字符串或列表。如果是列表,則第一項必須是NONE,CMD或CMD-SHELL。如果是字符串,則相當于指定CMD-SHELL后跟該字符串。
# Hit the local web app
test: ["CMD", "curl", "-f", "http://localhost"]
test: ["CMD-SHELL", "curl -f http://localhost || exit 1"]
test: curl -f https://localhost || exit 1
如果需要禁用鏡像的所有檢查項目,可以使用disable:true,相當于test:["NONE"]
healthcheck:disable: true
image
從指定的鏡像中啟動容器,可以是存儲倉庫、標簽以及鏡像 ID。
init
在容器內運行一個?init?來轉發信號和取得進程。將此選項設置true為服務啟用此功能。
version: "3.9"
services:web:image: alpine:latestinit: true
isolation
指定容器的隔離技術。在 Linux 上,唯一支持的值是default。在?Windows?上,可接受的值為default、process和hyperv。
labels
使用?Docker?標簽將元數據添加到容器,可以使用數組或字典。與?Dockerfile?中的LABELS類似:
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可以訪問db,并且設置別名為database:
version: "3.9"
services:web:build: .links:- "db:database"db:image: postgres
logging
日志記錄配置。
服務的日志記錄配置。
driver:
指定服務容器的日志記錄驅動程序,默認值為json-file。
有以下三個選項 "json-file" "syslog" "none"
json-file
僅在?json-file?驅動程序下,可以使用以下參數,限制日志得數量和大小。
當達到文件限制上限,會自動刪除舊得文件。
version: "3.9"
services:some-service:image: some-servicelogging:driver: "json-file"options:max-size: "200k"max-file: "10"
network_mode
syslog
syslog驅動程序下,可以使用?syslog-address?指定日志接收地址。
logging:driver: syslogoptions:syslog-address: "tcp://192.168.0.42:123"
network_mode
網絡模式。使用與 docker 客戶端--network相同,可以使用特殊形式service:[service name]。
host or none 使用主機的網絡堆棧,或者不使用網絡。
相當于docker run --net=host或docker run --net=none。
僅在使用docker stack命令時使用。
如果docker-compose使用該命令,請改用 network_mode。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
pid
pid將 PID 模式設置為主機 PID 模式。
這會在容器和主機操作系統之間共享?PID?地址空間。
使用此標志啟動的容器可以訪問和操作裸機命名空間中的其他容器,反之亦然。
pid: "host"
ports
暴露端口。
簡短語法
共有三種寫法:
- 指定兩個端口 (?HOST:CONTAINER)
- 僅指定容器端口(為主機端口選擇了一個臨時主機端口)。
- 指定要綁定到兩個端口的主機IP?地址(默認為?0.0.0.0,表示所有接口):(?IPADDR:HOSTPORT:CONTAINERPORT)。如果?HOSTPORT?為空(例如127.0.0.1::80),則會選擇一個臨時端口來綁定到主機上。
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"- "127.0.0.1::5000"- "6060:6060/udp"- "12400-12500:1240"
長語法
- target: 容器內的端口
- published: 公開的端口
- protocol:端口協議(tcp或udp)
- mode:host用于在每個節點上發布主機端口,或ingress用于負載平衡的群模式端口。
ports:- target: 80published: 8080protocol: tcpmode: host
profiles
允許通過有選擇地啟用服務來針對各種用途和環境調整?Compose?應用程序模型。這是通過將每個服務分配給單個或多個配置文件來實現的。如果未分配,則始終啟動該服務,但如果已分配,則僅在激活配置文件時才啟動。
這允許人們在單個docker-compose.yml文件中定義額外的服務,這些服務應該只在特定場景中啟動,例如用于調試或開發任務。
profiles: ["frontend", "debug"]
profiles:- frontend- debug
secrets
存儲敏感數據,例如密碼。為每個服務機密授予相應的訪問權限
簡短語法
簡短的語法僅指定機密名稱。
以下示例授予redis服務對my_secret和my_other_secret機密的訪問權限。./my_secret.txt文件的內容被設置為 my_secret,my_other_secret被定義為外部機密,這意味著它已經在Docker中定義,無論是通過運行docker secret create命令還是通過另一個堆棧部署,都不會重新創建。如果外部機密不存在,堆棧部署將失敗并顯示secret not found錯誤。
version: "3.9"
services:redis:image: redis:latestdeploy:replicas: 1environment:MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secretsecrets:- my_secret- my_other_secret
secrets:my_secret:file: ./my_secret.txtmy_other_secret:external: true
長語法
- source:定義機密標識符。
- target:要掛載在/run/secrets/服務的任務容器中的文件的名稱,默認是?source。
- uid和gid:/run/secrets/在服務的任務容器中擁有文件的數字?UID?或?GID?。
- mode:要掛載在/run/secrets/?服務的任務容器中的文件的權限,以八進制表示法。例如,0444?代表可讀。
下面的示例表示將my_secret?命名為redis_secret,模式為0440(組可讀),和用戶組為103。該redis服務無權訪問該my_other_secret機密。
version: "3.9"
services:redis:image: redis:latestdeploy:replicas: 1secrets:- source: my_secrettarget: redis_secretuid: '103'gid: '103'mode: 0440
secrets:my_secret:file: ./my_secret.txtmy_other_secret:external: true
一級secrets詳細配置:
- file:使用指定路徑中的文件內容創建機密。
- external:如果設置為?true,則指定此機密已創建。Docker?不會嘗試創建它,如果它不存在, 會報錯secret not found。
- name:Docker 中秘密對象的名稱。此字段可用于引用包含特殊字符的機密。
- template_driver:要使用的模板驅動程序的名稱,它控制是否以及如何將機密負載評估為模板。如果未設置驅動程序,則不使用模板。當前支持的唯一驅動程序是golang,它使用golang。
在本示例中,my_first_secret在<stack_name>_my_first_secret?部署堆棧時創建 ,并且my_second_secret已存在于?Docker?中。
secrets:my_first_secret:file: ./secret_datamy_second_secret:external: true
security_opt
為每個容器覆蓋默認的標簽。簡單說來就是管理全部服務的標簽,比如設置全部服務的?user?標簽值為USER。
security_opt修改容器默認的?schema?標簽。
security-opt:- label:user:USER # 設置容器的用戶標簽- label:role:ROLE # 設置容器的角色標簽- label:type:TYPE # 設置容器的安全策略標簽- label:level:LEVEL # 設置容器的安全等級標簽
stop_grace_period
指定在嘗試停止容器時等待多長時間。
stop_grace_period指定在容器無法處理?SIGTERM?(或者任何?stop_signal?的信號),等待多久后發送 SIGKILL 信號關閉容器。默認的等待時間是 10 秒。
- stop_grace_period: 1s # 等待 1 秒
- stop_grace_period: 1m30s # 等待 1 分 30 秒
在docker stop命令執行的時候,會先向容器中的進程發送系統信號SIGTERM,然后等待容器中的應用程序終止執行。如果等待時間達到設定的超時時間,或者默認的10秒,會繼續發送SIGKILL的系統信號強行kill掉進程。
在容器中的應用程序,可以選擇忽略和不處理SIGTERM信號,不過一旦達到超時時間,程序就會被系統強行kill掉,因為SIGKILL信號是直接發往系統內核的,應用程序沒有機會去處理它。
stop_grace_period: 1s
默認情況下,stop在發送 SIGKILL 之前等待容器退出 10 秒。
stop_signal
設置一個替代信號來停止容器。默認情況下stop使用?SIGTERM。使用stop_signal設置替代信號來stop。
stop_signal: SIGUSR1
sysctls
在容器中設置的內核參數,可以為數組或字典
sysctls:net.core.somaxconn: 1024net.ipv4.tcp_syncookies: 0
tmpfs
在容器內掛載一個臨時文件系統。可以是單個值或列表。
tmpfs: /run
# or
tmpfs:- /run- /tmp
ulimits
設置當前進程以及其子進程的資源使用量,覆蓋容器的默認限制,可以單一地將限制值設為一個整數,也可以將soft/hard限制指定為映射
ulimits:nproc: 65535nofile:soft: 20000hard: 40000
userns_mode
如果 Docker 守護程序配置了用戶命名空間,則禁用此服務的用戶命名空間。
userns_mode:"host"
volumes
掛載一個目錄或者一個已存在的數據卷容器,可以直接使用HOST:CONTAINER這樣的格式,或者使用HOST:CONTAINER:ro這樣的格式,后者對于容器來說,數據卷是只讀的,這樣可以有效保護宿主機的文件系統
您可以將主機路徑掛載為單個服務定義的一部分,無需在一級volumes鍵中定義它。
但是,如果您想在多個服務中重用一個卷,則需要在一級volumes 中定義一個命名卷。
如下實例,web 服務使用命名卷 (mydata),以及為單個服務定義的綁定安裝(dbservice下的第一個路徑volumes)。db服務還使用名為dbdata(dbservice下的第二個路徑volumes)的命名卷,使用了舊字符串格式定義它以安裝命名卷。命名卷必須列在頂級volumes鍵下。
version: "3.9"
services:web:image: nginx:alpinevolumes:- type: volumesource: mydatatarget: /datavolume:nocopy: true- type: bindsource: ./statictarget: /opt/app/staticdb:image: postgres:latestvolumes:- "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"- "dbdata:/var/lib/postgresql/data"volumes:mydata:dbdata:
簡短語法
簡短語法使用通用[SOURCE:]TARGET[:MODE]格式,其中?SOURCE可以是主機路徑或卷名。TARGET是安裝卷的容器路徑。標準模式ro用于只讀和rw讀寫(默認)。
您可以在主機上掛載一個相對路徑,該路徑相對于正在使用的 Compose 配置文件的目錄展開。相對路徑應始終以.或開頭..。
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# 命名卷- datavolume:/var/lib/mysql
長語法
(v3.2 新增的語法格式)
- type: 安裝類型,?bind,tmpfs或npipe
- source: 安裝源、主機上用于綁定安裝的路徑或在頂級volumes 中定義的卷的名稱 。不適用于 tmpfs 掛載。
- target:安裝卷的容器中的路徑
- read_only: 將卷設置為只讀的標志
- bind: 配置額外的綁定選項
- propagation:用于綁定的傳播模式
- volume: 配置額外的選項
- nocopy: 創建卷時禁用從容器復制數據的標志
- tmpfs: 配置額外的 tmpfs 選項
- size:tmpfs 掛載的大小(以字節為單位)
version: "3.9"
services:web:image: nginx:alpineports:- "80:80"volumes:- type: volumesource: mydatatarget: /datavolume:nocopy: true- type: bindsource: ./statictarget: /opt/app/staticnetworks:webnet:volumes:mydata:
一級 Volume 詳細配置:
- driver?指定該卷應使用哪個卷驅動程序
- driver_opts?將選項列表指定為鍵值對以傳遞給此卷的驅動程序
volumes:example:driver_opts:type: "nfs"o: "addr=10.40.0.199,nolock,soft,rw"device: ":/docker/example"
- external?如果設置為true,則指定該卷是在 Compose 之外創建的
- labels?添加元數據
- name?為此卷設置自定義名稱
version: "3.9"
volumes:data:name: my-app-data
變量置換
你可以使用?$VARIABLE?或者?${VARIABLE}?來置換變量
- ${VARIABLE:-default}VARIABLE在環境中未設置或為空時設置為default。
- ${VARIABLE-default}僅當VARIABLE在環境中未設置時才設置為default。
- ${VARIABLE:?err}退出并顯示一條錯誤消息,其中包含環境中的errif?VARIABLE未設置或為空。
- ${VARIABLE?err}退出并顯示一條錯誤消息,其中包含errif?VARIABLE在環境中未設置。
- 如果想使用一個不被compose處理的變量,可用使用?$$