本文是《Docker必知必會(huì)系列》第十二篇陶缺,原文發(fā)布于個(gè)人博客:悟塵紀(jì)。
前言
Compose 配置文件采用 YAML 格式洁灵,用于定義 services(服務(wù)), networks(網(wǎng)絡(luò))和 volumes(卷)饱岸。
文件的默認(rèn)路徑為./docker-compose.yml
。有多種版本格式——1徽千、2苫费、2.x 和3.x。 有關(guān)每個(gè)版本與Docker的兼容性双抽、包含哪些內(nèi)容以及如何升級(jí)的最新信息百框,請(qǐng)參閱官方文檔: 關(guān)于版本和升級(jí)。
服務(wù)定義包含應(yīng)用于該服務(wù)啟動(dòng)的每個(gè)容器的配置牍汹,就像將命令行參數(shù)傳遞給 docker run
一樣铐维。同樣,網(wǎng)絡(luò)和卷定義類似于 docker network create
和docker volume create
慎菲。
與 docker run
一樣嫁蛇,Dockerfile 中指定的選項(xiàng),例如 CMD
露该、 EXPOSE
睬棚、 VOLUME
、 ENV
,在缺省情況下都是遵守的——不需要再次以 docker-compose
方式指定它們抑党。
您可以使用類似 Bash 的${VARIABLE}
語(yǔ)法在配置值中使用環(huán)境變量 - 有關(guān)完整詳細(xì)信息空盼,請(qǐng)參見(jiàn)變量替換。
文件結(jié)構(gòu)和示例
這是一個(gè)投票應(yīng)用程序的 Compose 文件示例:
version: "3.8"
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:
配置指令
build
指定 Dockerfile
所在文件夾的路徑,Compose
將會(huì)利用它自動(dòng)構(gòu)建鏡像新荤。如:
version: '3.8'
services:
webapp:
build: ./dir
context、dockerfile和args
可以使用 context
指定文件夾路徑(可以是包含 Dockerfile 的目錄路徑台汇,也可以是 git 存儲(chǔ)庫(kù)的 url)苛骨,使用 dockerfile
指定 Dockerfile
文件名,使用 arg
為 Dockerfile
中的變量賦值苟呐。如:
version: '3.8'
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
如果在 build
同時(shí)指定了 image
痒芝,那么 Compose 會(huì)使用在 image
中指定的名字和標(biāo)簽來(lái)命名最終構(gòu)建的鏡像。如:
build: ./dir
image: webapp:tag
這將從 ./dir
構(gòu)建牵素,生成名為 webapp
严衬,標(biāo)簽為:tag
的鏡像。
cache_from
可以使用 cache_from
指定構(gòu)建鏡像時(shí)使用的緩存:
build:
context: .
cache_from:
- alpine:latest
- corp/web_app:3.14
labels
通過(guò)標(biāo)簽向生成的鏡像添加元數(shù)據(jù):
build:
context: .
labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
build:
context: .
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
network
設(shè)置構(gòu)建期間 run
指令要鏈接的網(wǎng)絡(luò):
build:
context: .
network: host # 可以設(shè)置為 none 禁用網(wǎng)絡(luò)
sim_size
設(shè)置所構(gòu)建容器的/dev/shm
分區(qū)大邪蚀簟:
build:
context: .
shm_size: '2gb'
target
按照在 Dockerfile
中定義的方式構(gòu)建指定的階段请琳。 有關(guān)詳細(xì)信息,請(qǐng)參閱 多階段構(gòu)建 文檔赠幕。
build:
context: .
target: prod
cap_add, cap_drop
添加或刪除容器的內(nèi)核能力:
cap_add:
- ALL # 讓容器擁有所有能力
cap_drop:
- NET_ADMIN # 移除 NET_ADMIN 功能
- SYS_ADMIN # 移除 SYS_ADMIN 功能
cgroup_parent
指定父 cgroup
組俄精,意味著將繼承該組的資源限制,如:cgroup_parent: m-executor-abcd
command
覆蓋容器啟動(dòng)后默認(rèn)執(zhí)行的命令榕堰。如:command: echo "hello world"
configs
使用configs
按服務(wù)授予對(duì)配置的訪問(wèn)權(quán)限竖慧。詳細(xì)內(nèi)容請(qǐng)查看 官方文檔。
container_name
指定容器名稱逆屡。默認(rèn)將會(huì)使用 項(xiàng)目名稱_服務(wù)名稱_序號(hào)
這樣的格式圾旨。
container_name: lixl-web-container
注意: 指定容器名稱后,該服務(wù)將無(wú)法進(jìn)行擴(kuò)展(scale)魏蔗,因?yàn)?Docker 不允許多個(gè)容器具有相同的名稱砍的。
depends_on
指定服務(wù)之間的依賴關(guān)系,以便按順序啟動(dòng)服務(wù)莺治。以下例子中會(huì)先啟動(dòng) redis
db
再啟動(dòng) web
version: '3.8'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
注意:
web
服務(wù)不會(huì)等待redis
db
「完全啟動(dòng)」之后才啟動(dòng)挨约。如果需要等待服務(wù)準(zhǔn)備就緒,請(qǐng)參閱控制啟動(dòng)順序 獲取有關(guān)此問(wèn)題的更多信息以及解決該問(wèn)題的策略产雹。
deploy
僅用于 Swarm mode
诫惭,詳細(xì)內(nèi)容請(qǐng)查看 官方文檔。
devices
指定設(shè)備映射關(guān)系蔓挖。使用與 docker 客戶端 --device
相同的選項(xiàng)格式:
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
dns
自定義 DNS
服務(wù)器夕土,可以是單個(gè)值或列表。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 114.114.114.114
dns_search
配置 DNS
搜索域,可以是單個(gè)值或列表怨绣。
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
entrypoint
重寫(xiě)默認(rèn)入口點(diǎn)角溃,如:entrypoint: ["php", "-d", "memory_limit=-1", "vendor/bin/phpunit"]
env_file
從文件中添加環(huán)境變量±撼牛可以是單個(gè)值或列表减细。
如果通過(guò) docker-compose -f FILE
方式來(lái)指定了 Compose 文件,則 env_file
中變量的路徑相對(duì)于文件所在目錄赢笨。
在 environment
聲明的變量未蝌,會(huì)覆蓋這些值。即使這些值為空或未定義茧妒。
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
env文件中每一行必須符合 VAL=VAL
格式萧吠,以 #
開(kāi)頭的行被視為注釋,并被忽略桐筏≈叫停空行也會(huì)被忽略。
# 設(shè)置環(huán)境
PRCK_ENV=development
environment
設(shè)置環(huán)境變量梅忌。你可以使用數(shù)組或字典兩種格式狰腌。任何布爾值(True、 False牧氮、 yes癌别、 no)都需要用引號(hào)括起來(lái),以確保 YML 解析器不會(huì)將它們轉(zhuǎn)換為 True 或 False蹋笼。
只有名稱的變量會(huì)自動(dòng)解析為 Compose 運(yùn)行主機(jī)上對(duì)應(yīng)變量的值展姐,可以用來(lái)防止泄露不必要的數(shù)據(jù)。
environment:
RACK_ENV: development
SESSION_SECRET:
environment:
- RACK_ENV=development
- SESSION_SECRET
expose
在不將端口發(fā)布到主機(jī)的情況下公開(kāi)端口——它們只能被鏈接的服務(wù)訪問(wèn)剖毯。 只能指定內(nèi)部端口圾笨。
expose:
- "3000"
- "8000"
external_links
注意:不推薦使用,建議使用
networks
指令代替逊谋。
鏈接到 docker-compose.yml
外部的容器擂达,甚至并非 Compose
管理的外部容器。
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
extra_hosts
添加主機(jī)名映射胶滋,使用與 Docker 中的 --add-host
參數(shù)相同的值:
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
會(huì)在啟動(dòng)后的服務(wù)容器的 /etc/hosts
文件中添加如下兩條條目究恤。
162.242.195.82 somehost
50.31.209.229 otherhost
healthcheck
通過(guò)命令檢查容器是否健康運(yùn)行瓢湃。
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
test
必須是字符串或列表悟耘。 如果是一個(gè)列表,則第一個(gè)參數(shù)必須是 NONE
、 CMD
或 CMD-shell
。 如果它是一個(gè)字符串,那么它等價(jià)于指定 CMD-SHELL
,然后指定該字符串。以下寫(xiě)法效果是一樣的。
# 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
要禁用鏡像默認(rèn)健康檢查設(shè)置骚烧,可以使用 disable: true
。 這相當(dāng)于指定 test: ["NONE"]。
image
指定要從哪個(gè)鏡像啟動(dòng)容器肤视。如果鏡像在本地不存在愿汰,也沒(méi)有指定了 build
,Compose
將會(huì)嘗試?yán)∵@個(gè)鏡像跌宛。
image: ubuntu
image: example-registry.com:4000/postgresql
image: a4bc65fd
init
在容器中運(yùn)行一個(gè) init哎迄,用于轉(zhuǎn)發(fā)信號(hào)和回收進(jìn)程。 將此選項(xiàng)設(shè)置為 true颊糜,以便為服務(wù)啟用此特性鸟赫。
version: "3.8"
services:
web:
image: alpine:latest
init: true
默認(rèn)使用的 init 二進(jìn)制文件是 Tini朋沮,并安裝在守護(hù)進(jìn)程主機(jī)上的
/usr/libexec/docker-init
中。 可以通過(guò)init-path
配置選項(xiàng)將守護(hù)進(jìn)程配置為使用自定義 init 二進(jìn)制文件樊拓。
labels
為容器添加 Docker 元數(shù)據(jù)(metadata)信息纠亚。
labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
logging
配置日志選項(xiàng)。
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
驅(qū)動(dòng)程序名稱為服務(wù)的容器指定了一個(gè)日志驅(qū)動(dòng)程序筋夏,與 docker 運(yùn)行 ---log-driver
選項(xiàng)一樣蒂胞。
driver: "json-file" # 默認(rèn)值
driver: "syslog"
driver: "none"
只有
json-file
和journald
驅(qū)動(dòng)程序可以直接從docker-compose up
和docker-compose logs
中獲得日志。 使用其他驅(qū)動(dòng)程序都不打印日志条篷。
可以使用 options
配置日志驅(qū)動(dòng)的相關(guān)參數(shù)骗随。與 docker run
的 --log-opt
選項(xiàng)一樣。如 json-file
支持的:
options:
max-size: "200k"
max-file: "10"
network_mode
設(shè)置網(wǎng)絡(luò)模式拥娄。和 docker run
的 --network
參數(shù)一樣蚊锹。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
networks
配置容器連接的網(wǎng)絡(luò)瞳筏。
services:
some-service:
networks:
- some-network
- other-network
networks:
some-network:
other-network:
aliases
同一網(wǎng)絡(luò)上的其他容器可以使用服務(wù)名稱或這個(gè)別名連接到服務(wù)的一個(gè)容器稚瘾。由于別名是網(wǎng)絡(luò)范圍的,同一個(gè)服務(wù)在不同的網(wǎng)絡(luò)上可以有不同的別名姚炕。
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:
在上面的示例中摊欠,提供了三個(gè)服務(wù)(web
、 worker
和 db
)以及兩個(gè)網(wǎng)絡(luò)(new
和 legacy
)柱宦。 db
服務(wù)在 new
網(wǎng)絡(luò)上的主機(jī)名為 db
或 database
些椒,在 legacy
網(wǎng)絡(luò)上主機(jī)名為 db
或 mysql
。
pid
將 PID 模式設(shè)置為 host
掸刊,將與主機(jī)系統(tǒng)共享進(jìn)程命名空間免糕。使用此標(biāo)志啟動(dòng)的容器可以訪問(wèn)和操作宿主機(jī)名稱空間中的其他容器,反之亦然忧侧。
ports
暴露端口信息石窑。使用 HOST:CONTAINER
格式,或者僅指定容器端口(宿主機(jī)將隨機(jī)選擇端口)都可以蚓炬。
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"
當(dāng)使用
HOST:CONTAINER
格式來(lái)映射端口時(shí)松逊,如果使用的容器端口小于 60 并且沒(méi)放到引號(hào)里,可能會(huì)得到錯(cuò)誤結(jié)果肯夏,因?yàn)?YAML
會(huì)自動(dòng)解析xx:yy
這種數(shù)字格式為 60 進(jìn)制经宏。為避免出現(xiàn)這種問(wèn)題犀暑,建議數(shù)字串都采用引號(hào)包括起來(lái)的字符串格式。
secrets
存儲(chǔ)敏感數(shù)據(jù)烁兰,例如 mysql
服務(wù)密碼耐亏。
version: "3.8"
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
以上示例授予redis
服務(wù)對(duì)my_secret
和my_other_secret
秘密的訪問(wèn)權(quán)限。 my_secret
的值設(shè)置為文件./my_secret.txt
的內(nèi)容缚柏,并將 my_other_secret
定義為外部資源苹熏,這意味著它已經(jīng)在Docker中定義,可以通過(guò)運(yùn)行docker secret create
命令進(jìn)行定義币喧。如果外部機(jī)密不存在轨域,則部署將失敗并顯示secret not found
錯(cuò)誤。
security_opt
指定容器模板標(biāo)簽(label)機(jī)制的默認(rèn)屬性(用戶杀餐、角色干发、類型、級(jí)別等)史翘。例如配置標(biāo)簽的用戶名和角色名枉长。
security_opt:
- label:user:USER
- label:role:ROLE
stop_grace_period
指定 stop_signal
在發(fā)送 SIGKILL
之前,如果容器無(wú)法處理 SIGTERM
(或已使用指定的任何停止信號(hào))而試圖停止容器的等待時(shí)間 琼讽。
stop_grace_period: 1s
stop_grace_period: 1m30s
默認(rèn)情況下必峰,stop
在發(fā)送 SIGKILL
之前等待10秒以退出容器。
stop_signal
設(shè)置替代信號(hào)來(lái)停止容器钻蹬。在默認(rèn)情況下使用的是 SIGTERM 停止容器吼蚁。
stop_signal: SIGUSR1
sysctls
配置容器內(nèi)核參數(shù)。
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
tmpfs
掛載一個(gè)臨時(shí)文件系統(tǒng)到容器问欠。
tmpfs: /run
tmpfs:
- /run
- /tmp
ulimits
指定容器的 ulimits 限制值肝匆。
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
volumes
數(shù)據(jù)卷所掛載路徑設(shè)置∷诚祝可以設(shè)置為宿主機(jī)路徑(HOST:CONTAINER
)或者數(shù)據(jù)卷名稱(VOLUME:CONTAINER
)旗国,并且可以設(shè)置訪問(wèn)模式 (HOST:CONTAINER:ro
)。
該指令中路徑支持相對(duì)路徑注整。
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
如果路徑為數(shù)據(jù)卷名稱能曾,必須在文件中配置數(shù)據(jù)卷。
version: "3"
services:
my_sql:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
其它指令
此外肿轨,還有包括 domainname, hostname, ipc, mac_address, privileged, read_only, shm_size, restart, stdin_open, tty, user, working_dir
等指令寿冕,基本跟 docker run
中對(duì)應(yīng)參數(shù)的功能一致。
指定容器中運(yùn)行應(yīng)用的用戶名萝招。
user: nginx
指定容器中工作目錄蚂斤。
working_dir: /code
指定容器中搜索域名、主機(jī)名槐沼、mac 地址等曙蒸。
domainname: your_website.com
hostname: test
mac_address: 08-00-27-00-0C-0A
允許容器中運(yùn)行一些特權(quán)命令捌治。
privileged: true
指定容器退出后的重啟策略為始終重啟。該命令對(duì)保持服務(wù)始終運(yùn)行十分有效纽窟,在生產(chǎn)環(huán)境中推薦配置為 always
或者 unless-stopped
肖油。
restart: always
以只讀模式掛載容器的 root 文件系統(tǒng),意味著不能對(duì)容器內(nèi)容進(jìn)行修改臂港。
read_only: true
打開(kāi)標(biāo)準(zhǔn)輸入森枪,可以接受外部輸入。
stdin_open: true
模擬一個(gè)偽終端审孽。
tty: true
讀取變量
Compose 模板文件支持動(dòng)態(tài)讀取主機(jī)的系統(tǒng)環(huán)境變量和當(dāng)前目錄下的 .env
文件中的變量县袱。
例如,下面的 Compose 文件將從運(yùn)行它的環(huán)境中讀取變量 ${MONGO_VERSION}
的值佑力,并寫(xiě)入執(zhí)行的指令中式散。
version: "3"
services:
db:
image: "mongo:${MONGO_VERSION}"
如果執(zhí)行 MONGO_VERSION=3.2 docker-compose up
則會(huì)啟動(dòng)一個(gè) mongo:3.2
鏡像的容器。
若當(dāng)前目錄存在 .env
文件打颤,執(zhí)行 docker-compose
命令時(shí)將從該文件中讀取變量暴拄。
在當(dāng)前目錄新建 .env
文件并寫(xiě)入以下內(nèi)容。
# 支持注釋
MONGO_VERSION=3.6
執(zhí)行 docker-compose up
則會(huì)啟動(dòng)一個(gè) mongo:3.6
鏡像的容器编饺。
參考
- 官方文檔: Compose file
- Compose文件示例:Awesome compose
- Compose模板文件
相關(guān)文章
- 上一篇:Docker必知必會(huì)系列(附錄3):Docker-compose 命令使用指南
- 下一篇:沒(méi)有了
寫(xiě)在最后
至此乖篷,本系列文章已經(jīng)閱讀完成。
獲取最新內(nèi)容透且,請(qǐng)?jiān)L問(wèn)我的個(gè)人博客:悟塵紀(jì)撕蔼。