轉(zhuǎn)載請(qǐng)注明出處:Docker-Compose學(xué)習(xí)使用

1. 什么是docker-compose
Docker Compose是一個(gè)用來(lái)定義和運(yùn)行復(fù)雜應(yīng)用的Docker工具。一個(gè)使用Docker容器的應(yīng)用,通常由多個(gè)容器組成。使用Docker Compose不再需要使用shell腳本來(lái)啟動(dòng)容器。
Compose 通過(guò)一個(gè)配置文件來(lái)管理多個(gè)Docker容器,在配置文件中,所有的容器通過(guò)services來(lái)定義,然后使用docker-compose腳本來(lái)啟動(dòng),停止和重啟應(yīng)用,和應(yīng)用中的服務(wù)以及所有依賴服務(wù)的容器,非常適合組合使用多個(gè)容器進(jìn)行開(kāi)發(fā)的場(chǎng)景。
2. 安裝
docker-compose安裝可以參考官方文檔:Install Docker Compose
2.1. macOs
Docker Desktop for Mac 和 Docker Toolbox 已集成了docker-compose, 所以只要安裝了docker是不需要安裝的,直接就可以用。
2.2. Linux
在Linux系統(tǒng)中,可以通過(guò)源碼來(lái)安裝docker-compose
- 從github下載最新版docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- 給docker-compose賦予可執(zhí)行權(quán)限
sudo chmod +x /usr/local/bin/docker-compose
最后可以通過(guò)以下命令來(lái)驗(yàn)證是否安裝成功:
docker-compose --version
3. 語(yǔ)法
docker-compose 文件命名以.yml或.yaml為后綴。
下面先欣賞一下官方文檔中的一個(gè)示例:
version: "3"
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:
從上述示例看,整個(gè)文檔分為4部分,version, services, networks, volumes, 其中services中內(nèi)容最長(zhǎng),下面將一一做個(gè)簡(jiǎn)單介紹
3.1. version
version是compose的版本,下表是compose版本與docker版本對(duì)照表:
| 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.2. services
services是用來(lái)配置定義每個(gè)容器啟動(dòng)參數(shù),每個(gè)service就是一個(gè)容器,services下一級(jí)配置即是服務(wù)名稱,例如上面示例中的redis, db等。
3.2.1. image
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
3.2.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è)名字。
既然可以在 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.2.3. command
使用 command 可以覆蓋容器啟動(dòng)后默認(rèn)執(zhí)行的命令。
command: bundle exec thin -p 3000
也可以寫成類似 Dockerfile 中的格式:
command: [bundle, exec, thin, -p, 3000]
3.2.4. container_name
Compose 的容器名稱格式是:<項(xiàng)目名稱><服務(wù)名稱><序號(hào)>
雖然可以自定義項(xiàng)目名稱、服務(wù)名稱,但是如果你想完全控制容器的命名,可以使用這個(gè)標(biāo)簽指定:
container_name: app
這樣容器的名字就指定為 app 了。
3.2.5. depends_on
在使用 Compose 時(shí),最大的好處就是少打啟動(dòng)命令,但是一般項(xiàng)目容器啟動(dòng)的順序是有要求的,如果直接從上到下啟動(dòng)容器,必然會(huì)因?yàn)槿萜饕蕾噯?wèn)題而啟動(dòng)失敗。
例如在沒(méi)啟動(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)系。
3.2.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
3.2.7. environment
和 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
3.2.8. 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
3.2.9. 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"
3.2.10 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)建。
3.2.11 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)制。所以建議采用字符串格式。
3.2.12. 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
3.2.13. 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ò)有不同的別名。
3.2.14. 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ò)。
4. 常用命令
docker-compose常用命令可以通過(guò)以下命令大致看一下:
docker-compose --help
結(jié)果如下:
Define and run multi-container applications with Docker.
Usage:
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
docker-compose -h|--help
Options:
-f, --file FILE Specify an alternate compose file
(default: docker-compose.yml)
-p, --project-name NAME Specify an alternate project name
(default: directory name)
--verbose Show more output
--log-level LEVEL Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
--no-ansi Do not print ANSI control characters
-v, --version Print version and exit
-H, --host HOST Daemon socket to connect to
--tls Use TLS; implied by --tlsverify
--tlscacert CA_PATH Trust certs signed only by this CA
--tlscert CLIENT_CERT_PATH Path to TLS certificate file
--tlskey TLS_KEY_PATH Path to TLS key file
--tlsverify Use TLS and verify the remote
--skip-hostname-check Don't check the daemon's hostname against the
name specified in the client certificate
--project-directory PATH Specify an alternate working directory
(default: the path of the Compose file)
--compatibility If set, Compose will attempt to convert deploy
keys in v3 files to their non-Swarm equivalent
Commands:
build Build or rebuild services
bundle Generate a Docker bundle from the Compose file
config Validate and view the Compose file
create Create services
down Stop and remove containers, networks, images, and volumes
events Receive real time events from containers
exec Execute a command in a running container
help Get help on a command
images List images
kill Kill containers
logs View output from containers
pause Pause services
port Print the public port for a port binding
ps List containers
pull Pull service images
push Push service images
restart Restart services
rm Remove stopped containers
run Run a one-off command
scale Set number of containers for a service
start Start services
stop Stop services
top Display the running processes
unpause Unpause services
up Create and start containers
version Show the Docker-Compose version information
下面會(huì)針對(duì)一些比較常用的命令進(jìn)行簡(jiǎn)單介紹
4.1. build
當(dāng)修改dockerfile或者docker-compose時(shí),運(yùn)行docker-compose build 重建鏡像。 生成鏡像后,可使用docker-compose up啟動(dòng)
4.2. ps
顯示所有容器信息,默認(rèn)顯示name、command、state、ports。
4.3. kill
強(qiáng)制停止某個(gè)正在運(yùn)行的服務(wù)
4.4. logs
打印服務(wù)日志
語(yǔ)法:
logs [options] [SERVICE...]
參數(shù):
--no-color Produce monochrome output.
-f, --follow Follow log output
-t, --timestamps Show timestamps
--tail="all" Number of lines to show from the end of the logs
for each container.
4.5. up
構(gòu)建,(重新)創(chuàng)建,啟動(dòng),鏈接一個(gè)服務(wù)相關(guān)的容器。鏈接的服務(wù)都將會(huì)啟動(dòng),除非他們已經(jīng)運(yùn)行。默認(rèn)情況, docker-compose up 將會(huì)整合所有容器的輸出,并且退出時(shí),所有容器將會(huì)停止。如果使用 docker-compose up -d ,將會(huì)在后臺(tái)啟動(dòng)并運(yùn)行所有的容器。
默認(rèn)情況,如果該服務(wù)的容器已經(jīng)存在, docker-compose up 將會(huì)停止并嘗試重新創(chuàng)建他們(保持使用 volumes-from 掛載的卷),以保證 docker-compose.yml的修改生效。如果你不想容器被停止并重新創(chuàng)建,可以使用 docker-compose up --no-recreate。如果需要的話,這樣將會(huì)啟動(dòng)已經(jīng)停止的容器。
語(yǔ)法:
up [options] [--scale SERVICE=NUM...] [SERVICE...]
參數(shù):
-d 后臺(tái)運(yùn)行,輸出容器的名字.
Incompatible with --abort-on-container-exit.
--no-color 單色輸出.
--no-deps 不啟動(dòng)link服務(wù).
--force-recreate 強(qiáng)制重新創(chuàng)建compose服務(wù),即使沒(méi)有任何改變。重新創(chuàng)建后啟動(dòng)容器
Incompatible with --no-recreate.
--no-recreate 如果容器已經(jīng)存在,不重新創(chuàng)建.
Incompatible with --force-recreate.
--no-build 不創(chuàng)建重啟,即使鏡像不存在.
--build 重新創(chuàng)建鏡像,然后生成容器.
--abort-on-container-exit 任何容器停止,自動(dòng)停止所有容器.
Incompatible with -d.
-t, --timeout TIMEOUT 超時(shí)時(shí)間. (default: 10)
--remove-orphans 移除compose文件中未定義服務(wù)的容器
4.6. create
為服務(wù)創(chuàng)建容器.只是單純的create,還需要使用start啟動(dòng)compose
語(yǔ)法:
create [options] [SERVICE...]
參數(shù)
--force-recreate 重新創(chuàng)建容器,即使他的配置和鏡像沒(méi)有改變,不兼容--no-recreate參數(shù)
--no-recreate 如果容器已經(jīng)存在,不需要重新創(chuàng)建. 不兼容--force-recreate參數(shù)
--no-build 不創(chuàng)建鏡像,即使缺失.
--build 創(chuàng)建容器前,生成鏡像
4.7. down
停止和刪除容器、網(wǎng)絡(luò)、卷、鏡像,這些內(nèi)容是通過(guò)docker-compose up命令創(chuàng)建的. 默認(rèn)值刪除容器網(wǎng)絡(luò),可以通過(guò)指定 rmi volumes參數(shù)刪除鏡像和卷。
語(yǔ)法:
down [options]
參數(shù):
--rmi type 刪除鏡像,類型必須是:
'all': 刪除compose文件中定義的所以鏡像.
'local': 刪除鏡像名為空的鏡像
-v, --volumes 刪除卷
attached to containers.
--remove-orphans Remove containers for services not defined in the
Compose file
4.8. start
啟動(dòng)一個(gè)已經(jīng)存在的服務(wù)容器。
4.9. stop
停止一個(gè)已經(jīng)運(yùn)行的容器,但不刪除它。通過(guò) docker-compose start可以再次啟動(dòng)這些容器。
4.10. pause
暫停容器服務(wù),docker-compose pause 暫停所有服務(wù)。docker-compose pause web,暫停web服務(wù)的容器。
4.11. unpause
恢復(fù)容器服務(wù),docker-compose unpause 恢復(fù)所有服務(wù),docker-compose unpause web,恢復(fù)web服務(wù)的容器。
4.12. restart
重啟docker-compose.yml中定義的所有的已停止的和正在運(yùn)行的服務(wù)。
4.13. rm
刪除已經(jīng)停止的容器,如果服務(wù)在運(yùn)行,需要先docker-compose stop 停止容器,默認(rèn)情況下,已掛載的volume中的數(shù)據(jù)不會(huì)被刪除,可以使用docker volume ls查看所有的volume情況。所有在容器中并未在volume中的數(shù)據(jù)將被刪除。
4.14. run
在一個(gè)服務(wù)上執(zhí)行一個(gè)命令.
語(yǔ)法:
run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] [-l KEY=VALUE...]
SERVICE [COMMAND] [ARGS...]
參數(shù):
-d 后臺(tái)運(yùn)行,輸出容器名.
-e KEY=VAL 設(shè)置環(huán)境變量參數(shù),可以使用多次
-u, --user="" 指定運(yùn)行的用戶
--no-deps 不啟動(dòng)link服務(wù),只啟動(dòng)run的服務(wù).
--rm 運(yùn)行后刪除容器,后臺(tái)運(yùn)行模式除外(-d).
-p, --publish=[] 開(kāi)放端口
--service-ports compose文件中配置什么端口,就映射什么端口.
-T 禁用TTY.
-w, --workdir="" 設(shè)置工作目錄
例如:
docker-compose run ubuntu ping docker.com
4.15. scale
設(shè)置同一個(gè)服務(wù)運(yùn)行的容器個(gè)數(shù)。通過(guò) service=num 的參數(shù)來(lái)設(shè)置數(shù)量。
5. 參考文檔
官方文檔 - Docker Compose
docker-compose.yml 配置文件編寫詳解
docker-compose:基本語(yǔ)法
docker-compose命令詳解
完
轉(zhuǎn)載請(qǐng)注明出處:Docker-Compose學(xué)習(xí)使用