Docker-Compose簡(jiǎn)介安裝使用
[TOC]
1 簡(jiǎn)介
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.
Compose是定義和運(yùn)行多容器Docker應(yīng)用程序的工具,使用Compose,您可以使用YAML文件來(lái)配置應(yīng)用程序的服務(wù),然后,使用單個(gè)命令創(chuàng)建并啟動(dòng)配置中的所有服務(wù)
Dockerfile 可以讓用戶管理一個(gè)單獨(dú)的應(yīng)用容器。使用Docker Compose,不再需要使用shell腳本來(lái)啟動(dòng)容器。在配置文件中,所有的容器通過(guò)services
來(lái)定義,然后使用docker-compose
腳本來(lái)啟動(dòng),停止和重啟應(yīng)用,和應(yīng)用中的服務(wù)以及所有依賴服務(wù)的容器
2 安裝
方法一:
$curl -L https://github.com/docker/compose/releases/download/1.17.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$chmod +x /usr/local/bin/docker-compose
#查看版本
$docker-compose version
方法二:用pip方式安裝(備用)
#安裝pip
$yum -y install epel-release
$yum -y install python-pip
#確認(rèn)版本
$pip --version
#更新pip
$pip install --upgrade pip
#安裝docker-compose
$pip install docker-compose
#查看版本
$docker-compose version
3 使用
3.1 docker-comose命令
docker-compose [SUBCOMMAND]
完整的命令列表如下----- 官網(wǎng)
SUBCOMMAND | 解釋 |
---|---|
build | 構(gòu)建或重建服務(wù) |
help | 命令幫助 |
kill | 殺掉容器 |
logs | 顯示容器的輸出內(nèi)容 |
port | 打印綁定的開放端口 |
ps | 顯示容器 |
pull | 拉取服務(wù)鏡像 |
restart | 重啟服務(wù) |
rm | 刪除停止的容器 |
run | 運(yùn)行一個(gè)一次性命令 |
scale | 設(shè)置服務(wù)的容器數(shù)目 |
start | 開啟服務(wù) |
stop | 停止服務(wù) |
up | 創(chuàng)建并啟動(dòng)容器服務(wù)(-d:后臺(tái)啟動(dòng)) |
備注:執(zhí)行以上的命令大多數(shù)要在docker-compose.yml文件同級(jí)目錄中
3.2 docker-compose.yml 文件
示例:參考(Docker Compose 配置文件詳解)
version: '2'
services:
web:
image: dockercloud/hello-world
ports:
- 8080
networks:
- front-tier
- back-tier
redis:
image: redis
links:
- web
networks:
- back-tier
lb:
image: dockercloud/haproxy
ports:
- 80:80
links:
- web
networks:
- front-tier
- back-tier
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
front-tier:
driver: bridge
back-tier:
driver: bridge
可以看到一份標(biāo)準(zhǔn)配置文件應(yīng)該包含 version、services、networks 三大部分,其中最關(guān)鍵的就是 services 和 networks 兩個(gè)部分,下面先來(lái)看 services 的書寫規(guī)則。
1. image
services:
web:
image: hello-world
在 services 標(biāo)簽下的第二級(jí)標(biāo)簽是 web,這個(gè)名字是用戶自己自定義,它就是服務(wù)名稱。
image 則是指定服務(wù)的鏡像名稱或鏡像 ID。如果鏡像在本地不存在,Compose 將會(huì)嘗試?yán)∵@個(gè)鏡像。
例如下面這些格式都是可以的:
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd
2. build
服務(wù)除了可以基于指定的鏡像,還可以基于一份 Dockerfile,在使用 up 啟動(dòng)之時(shí)執(zhí)行構(gòu)建任務(wù),這個(gè)構(gòu)建標(biāo)簽就是 build,它可以指定 Dockerfile 所在文件夾的路徑。Compose 將會(huì)利用它自動(dòng)構(gòu)建這個(gè)鏡像,然后使用這個(gè)鏡像啟動(dòng)服務(wù)容器。
build: /path/to/build/dir
也可以是相對(duì)路徑,只要上下文確定就可以讀取到 Dockerfile。
build: ./dir
設(shè)定上下文根目錄,然后以該目錄為準(zhǔn)指定 Dockerfile。
build:
context: ../
dockerfile: path/of/Dockerfile
注意 build 都是一個(gè)目錄,如果你要指定 Dockerfile 文件需要在 build 標(biāo)簽的子級(jí)標(biāo)簽中使用 dockerfile 標(biāo)簽指定,如上面的例子。
如果你同時(shí)指定了 image 和 build 兩個(gè)標(biāo)簽,那么 Compose 會(huì)構(gòu)建鏡像并且把鏡像命名為 image 后面的那個(gè)名字。如下:鏡像名稱會(huì)是webapp:tag
build: ./dir
image: webapp:tag
既然可以在 docker-compose.yml 中定義構(gòu)建任務(wù),那么一定少不了 arg 這個(gè)標(biāo)簽,就像 Dockerfile 中的 ARG 指令,它可以在構(gòu)建過(guò)程中指定環(huán)境變量,但是在構(gòu)建成功后取消,在 docker-compose.yml 文件中也支持這樣的寫法:
build:
context: .
args:
buildno: 1
password: secret
下面這種寫法也是支持的,一般來(lái)說(shuō)下面的寫法更適合閱讀
build:
context: .
args:
- buildno=1
- password=secret
與 ENV 不同的是,ARG 是允許空值的。例如:
args:
- buildno
- password
這樣構(gòu)建過(guò)程可以向它們賦值。
注意:YAML 的布爾值(true, false, yes, no, on, off)必須要使用引號(hào)引起來(lái)(單引號(hào)、雙引號(hào)均可),否則會(huì)當(dāng)成字符串解析。
3. command
使用 command 可以覆蓋容器啟動(dòng)后默認(rèn)執(zhí)行的命令。
command: bundle exec thin -p 3000
也可以寫成類似 Dockerfile 中的數(shù)組格式:
command: [bundle, exec, thin, -p, 3000]
4. container_name
前面說(shuō)過(guò) Compose 的容器名稱格式是:<項(xiàng)目名稱><服務(wù)名稱><序號(hào)>
雖然可以自定義項(xiàng)目名稱、服務(wù)名稱,但是如果你想完全控制容器的命名,可以使用這個(gè)標(biāo)簽指定:
container_name: app
這樣容器的名字就指定為 app 了。
5. depends_on
在使用 Compose 時(shí),最大的好處就是少打啟動(dòng)命令,但是一般項(xiàng)目容器啟動(dòng)的順序是有要求的,如果直接從上到下啟動(dòng)容器,必然會(huì)因?yàn)槿萜饕蕾噯?wèn)題而啟動(dòng)失敗。
例如在沒啟動(dòng)數(shù)據(jù)庫(kù)容器的時(shí)候啟動(dòng)了應(yīng)用容器,這時(shí)候應(yīng)用容器會(huì)因?yàn)檎也坏綌?shù)據(jù)庫(kù)而退出,為了避免這種情況我們需要加入一個(gè)標(biāo)簽,就是 depends_on,這個(gè)標(biāo)簽解決了容器的依賴、啟動(dòng)先后的問(wèn)題。
例如下面容器會(huì)先啟動(dòng) redis 和 db 兩個(gè)服務(wù),最后才啟動(dòng) web 服務(wù):
version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
注意的是,默認(rèn)情況下使用 docker-compose up web 這樣的方式啟動(dòng) web 服務(wù)時(shí),也會(huì)啟動(dòng) redis 和 db 兩個(gè)服務(wù),因?yàn)樵谂渲梦募卸x了依賴關(guān)系。
6. dns
和 --dns 參數(shù)一樣用途,格式如下:
dns: 8.8.8.8
也可以是一個(gè)列表:
dns:
- 8.8.8.8
- 9.9.9.9
此外 dns_search 的配置也類似:
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
7. tmpfs
掛載臨時(shí)目錄到容器內(nèi)部,與 run 的參數(shù)一樣效果:
tmpfs: /run
tmpfs:
- /run
- /tmp
8. entrypoint
在 Dockerfile 中有一個(gè)指令叫做 ENTRYPOINT 指令,用于指定接入點(diǎn),第四章有對(duì)比過(guò)與 CMD 的區(qū)別。
在 docker-compose.yml 中可以定義接入點(diǎn),覆蓋 Dockerfile 中的定義:
entrypoint: /code/entrypoint.sh
格式和 Docker 類似,不過(guò)還可以寫成這樣:
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit
9. env_file
還記得前面提到的 .env 文件吧,這個(gè)文件可以設(shè)置 Compose 的變量。而在 docker-compose.yml 中可以定義一個(gè)專門存放變量的文件。
如果通過(guò) docker-compose -f FILE 指定了配置文件,則 env_file 中路徑會(huì)使用配置文件路徑。
如果有變量名稱與 environment 指令沖突,則以后者為準(zhǔn)。格式如下:
env_file: .env
或者根據(jù) docker-compose.yml 設(shè)置多個(gè):
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
注意的是這里所說(shuō)的環(huán)境變量是對(duì)宿主機(jī)的 Compose 而言的,如果在配置文件中有 build 操作,這些變量并不會(huì)進(jìn)入構(gòu)建過(guò)程中,如果要在構(gòu)建中使用變量還是首選前面剛講的 arg 標(biāo)簽。
10. environment
與上面的 env_file 標(biāo)簽完全不同,反而和 arg 有幾分類似,這個(gè)標(biāo)簽的作用是設(shè)置鏡像變量,它可以保存變量到鏡像里面,也就是說(shuō)啟動(dòng)的容器也會(huì)包含這些變量設(shè)置,這是與 arg 最大的不同。
一般 arg 標(biāo)簽的變量?jī)H用在構(gòu)建過(guò)程中。而 environment 和 Dockerfile 中的 ENV 指令一樣會(huì)把變量一直保存在鏡像、容器中,類似 docker run -e 的效果。
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
11. expose
這個(gè)標(biāo)簽與Dockerfile中的EXPOSE指令一樣,用于指定暴露的端口,但是只是作為一種參考,實(shí)際上docker-compose.yml的端口映射還得ports這樣的標(biāo)簽。
expose:
- "3000"
- "8000"
12. external_links
在使用Docker過(guò)程中,我們會(huì)有許多單獨(dú)使用docker run啟動(dòng)的容器,為了使Compose能夠連接這些不在docker-compose.yml中定義的容器,我們需要一個(gè)特殊的標(biāo)簽,就是external_links,它可以讓Compose項(xiàng)目里面的容器連接到那些項(xiàng)目配置外部的容器(前提是外部容器中必須至少有一個(gè)容器是連接到與項(xiàng)目?jī)?nèi)的服務(wù)的同一個(gè)網(wǎng)絡(luò)里面)。
格式如下:
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
13. extra_hosts
添加主機(jī)名的標(biāo)簽,就是往/etc/hosts文件中添加一些記錄,與Docker client的--add-host類似:
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
啟動(dòng)之后查看容器內(nèi)部hosts:
162.242.195.82 somehost
50.31.209.229 otherhost
14. labels
向容器添加元數(shù)據(jù),和Dockerfile的LABEL指令一個(gè)意思,格式如下:
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"
15. links
還記得上面的depends_on吧,那個(gè)標(biāo)簽解決的是啟動(dòng)順序問(wèn)題,這個(gè)標(biāo)簽解決的是容器連接問(wèn)題,與Docker client的--link一樣效果,會(huì)連接到其它服務(wù)中的容器。
格式如下:
links:
- db
- db:database
- redis
使用的別名將會(huì)自動(dòng)在服務(wù)容器中的/etc/hosts里創(chuàng)建。例如:
172.12.2.186 db
172.12.2.186 database
172.12.2.187 redis
相應(yīng)的環(huán)境變量也將被創(chuàng)建。
16. logging
這個(gè)標(biāo)簽用于配置日志服務(wù)。格式如下:
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
默認(rèn)的driver是json-file。只有json-file和journald可以通過(guò)docker-compose logs顯示日志,其他方式有其他日志查看方式,但目前Compose不支持。對(duì)于可選值可以使用options指定。
有關(guān)更多這方面的信息可以閱讀官方文檔:
https://docs.docker.com/engine/admin/logging/overview/
17. pid
pid: "host"
將PID模式設(shè)置為主機(jī)PID模式,跟主機(jī)系統(tǒng)共享進(jìn)程命名空間。容器使用這個(gè)標(biāo)簽將能夠訪問(wèn)和操縱其他容器和宿主機(jī)的名稱空間。
18. ports
映射端口的標(biāo)簽。
使用HOST:CONTAINER格式或者只是指定容器的端口,宿主機(jī)會(huì)隨機(jī)映射端口。
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"
注意:當(dāng)使用HOST:CONTAINER格式來(lái)映射端口時(shí),如果你使用的容器端口小于60你可能會(huì)得到錯(cuò)誤得結(jié)果,因?yàn)閅AML將會(huì)解析xx:yy這種數(shù)字格式為60進(jìn)制。所以建議采用字符串格式。
19. security_opt
為每個(gè)容器覆蓋默認(rèn)的標(biāo)簽。簡(jiǎn)單說(shuō)來(lái)就是管理全部服務(wù)的標(biāo)簽。比如設(shè)置全部服務(wù)的user標(biāo)簽值為USER。
security_opt:
- label:user:USER
- label:role:ROLE
20. stop_signal
設(shè)置另一個(gè)信號(hào)來(lái)停止容器。在默認(rèn)情況下使用的是SIGTERM停止容器。設(shè)置另一個(gè)信號(hào)可以使用stop_signal標(biāo)簽。
stop_signal: SIGUSR1
21. volumes
掛載一個(gè)目錄或者一個(gè)已存在的數(shù)據(jù)卷容器,可以直接使用 [HOST:CONTAINER] 這樣的格式,或者使用 [HOST:CONTAINER:ro] 這樣的格式,后者對(duì)于容器來(lái)說(shuō),數(shù)據(jù)卷是只讀的,這樣可以有效保護(hù)宿主機(jī)的文件系統(tǒng)。
Compose的數(shù)據(jù)卷指定路徑可以是相對(duì)路徑,使用 . 或者 .. 來(lái)指定相對(duì)目錄。
數(shù)據(jù)卷的格式可以是下面多種形式:
volumes:
// 只是指定一個(gè)路徑,Docker 會(huì)自動(dòng)在創(chuàng)建一個(gè)數(shù)據(jù)卷(這個(gè)路徑是容器內(nèi)部的)。
- /var/lib/mysql
// 使用絕對(duì)路徑掛載數(shù)據(jù)卷
- /opt/data:/var/lib/mysql
// 以 Compose 配置文件為中心的相對(duì)路徑作為數(shù)據(jù)卷掛載到容器。
- ./cache:/tmp/cache
// 使用用戶的相對(duì)路徑(~/ 表示的目錄是 /home/<用戶目錄>/ 或者 /root/)。
- ~/configs:/etc/configs/:ro
// 已經(jīng)存在的命名的數(shù)據(jù)卷。
- datavolume:/var/lib/mysql
如果你不使用宿主機(jī)的路徑,你可以指定一個(gè)volume_driver。
volume_driver: mydriver
22. volumes_from
從其它容器或者服務(wù)掛載數(shù)據(jù)卷,可選的參數(shù)是 :ro或者 :rw,前者表示容器只讀,后者表示容器對(duì)數(shù)據(jù)卷是可讀可寫的。默認(rèn)情況下是可讀可寫的。
volumes_from:
- service_name
- service_name:ro
- container:container_name
- container:container_name:rw
23. cap_add, cap_drop
添加或刪除容器的內(nèi)核功能。詳細(xì)信息在前面容器章節(jié)有講解,此處不再贅述。
cap_add:
- ALL
cap_drop:
- NET_ADMIN
- SYS_ADMIN
24. cgroup_parent
指定一個(gè)容器的父級(jí)cgroup。
cgroup_parent: m-executor-abcd
25. devices
設(shè)備映射列表。與Docker client的--device參數(shù)類似。
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
26. extends
這個(gè)標(biāo)簽可以擴(kuò)展另一個(gè)服務(wù),擴(kuò)展內(nèi)容可以是來(lái)自在當(dāng)前文件,也可以是來(lái)自其他文件,相同服務(wù)的情況下,后來(lái)者會(huì)有選擇地覆蓋原有配置。
extends:
file: common.yml
service: webapp
用戶可以在任何地方使用這個(gè)標(biāo)簽,只要標(biāo)簽內(nèi)容包含file和service兩個(gè)值就可以了。file的值可以是相對(duì)或者絕對(duì)路徑,如果不指定file的值,那么Compose會(huì)讀取當(dāng)前YML文件的信息。
更多的操作細(xì)節(jié)在后面的12.3.4小節(jié)有介紹。
27. network_mode
網(wǎng)絡(luò)模式,與Docker client的--net參數(shù)類似,只是相對(duì)多了一個(gè)service:[service name] 的格式。
例如:
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]
可以指定使用服務(wù)或者容器的網(wǎng)絡(luò)。
28. networks
加入指定網(wǎng)絡(luò),格式如下:
services:
some-service:
networks:
- some-network
- other-network
關(guān)于這個(gè)標(biāo)簽還有一個(gè)特別的子標(biāo)簽aliases,這是一個(gè)用來(lái)設(shè)置服務(wù)別名的標(biāo)簽,例如:
services:
some-service:
networks:
some-network:
aliases:
- alias1
- alias3
other-network:
aliases:
- alias2
相同的服務(wù)可以在不同的網(wǎng)絡(luò)有不同的別名。
29. 其它
還有這些標(biāo)簽:cpu_shares, cpu_quota, cpuset, domainname, hostname, ipc, mac_address, mem_limit, memswap_limit, privileged, read_only, restart, shm_size, stdin_open, tty, user, working_dir
上面這些都是一個(gè)單值的標(biāo)簽,類似于使用docker run的效果。
cpu_shares: 73
cpu_quota: 50000
cpuset: 0,1
user: postgresql
working_dir: /code
domainname: foo.com
hostname: foo
ipc: host
mac_address: 02:42:ac:11:65:43
mem_limit: 1000000000
memswap_limit: 2000000000
privileged: true
restart: always
read_only: true
shm_size: 64M
stdin_open: true
tty: true
4 note
4.1 docker run和docker-compose up
note:docker run 是創(chuàng)建新的容器 而docker-compose up 是會(huì)使用舊容器(如果存在的話)
官網(wǎng)介紹:
Preserve volume data when containers are created
Compose preserves all volumes used by your services. When docker-compose up runs, if it finds any containers from previous runs, it copies the volumes from the old container to the new container. This process ensures that any data you’ve created in volumes isn’t lost.
docker-compose
只會(huì)為每個(gè)鏡像維護(hù)一個(gè)實(shí)例,每次運(yùn)行docker-compose up
的時(shí)候,compose會(huì)查找之前的容器,把舊容器的volume-data拷貝到容器中。除非手動(dòng)用docker rm
命令刪除容器,否則CONTAINER ID不會(huì)發(fā)生改變。
這和docker run [images name]
不一樣,這個(gè)命令每次運(yùn)行會(huì)新生成一個(gè)鏡像的實(shí)例,即新容器,它們對(duì)應(yīng)的CONTAINER ID也各不相同
4.2 容器命名
docker-compose up -d
創(chuàng)建的容器的名字:是由docker-compose.yml的文件目錄名加文件中指定的名字作為前綴,使用數(shù)字作為后綴
ex:
cluster/docker-compose.yml
docker-compose.yml中指定兩個(gè)服務(wù):
web:
image:
command:
....
redis:
image:
command:
....
則創(chuàng)建的服務(wù)容器名為:cluster_web_1和cluster_redis_1
參考
1 Get started with Docker Compose
2017-12-8-Boy