Docker Compose
Outline:
Background of Docker Compose
部署要点
Compose文件示例
热部署
本节使用示例:here
Background
- 单引擎模式部署workflow:
- 编写定义多容器应用的YAML文件(称为Compose文件)
- 将其交给
docker compose
命令, - 该工具会基于docker api完成应用的部署( 即与docker daemon通信 )
Docker Compose是Docker Stack的简化版. 能够在Docker节点上以单引擎模式( Single-Engine Mode )进行简化版多服务应用的部署和管理
- 真正的多服务应用中, 服务是若干容器的集合, 作为一个整体进行统一管理. 例如Docker Stack
- Docker Compose中的一个服务就只有一个容器,因此是"简化版多服务应用"
Installation
See Install the Compose plugin
First, you need to install docker.
Update the package index, and install the latest version of Docker Compose. For Ubuntu and Debian, run:
1
2sudo apt-get update
sudo apt-get install docker compose-pluginVerify that Docker Compose is installed correctly by checking the version.
1
docker compose version
Basic Idea
通过Compose文件定义的多容器应用称为Compose应用
docker compose
构建应用时也会利用构建缓存,对于已有的镜像、网络、卷,不会再重新创建docker compose
的命令和docker comtainer
大同小异, 所谓的应用就是若干容器, 容器就有运行、停止和关闭三种状态。“关闭”指的是容器资源也被删除由于docker卷的生命周期是与相应的容器完全解耦的。 因此关闭Compose应用,卷不会被删除
同样,镜像也不会被删除
docker compose
会将项目名称和Compose文件中定义的服务名称连起来,作为新构建的镜像的名称, 而容器名称是镜像名称+数字后缀,因为docker compose
允许扩容
Commands
启动Compose应用
1 | docker compose up [ -f [compose_file_name] ] -d |
-f
: 指定Compose文件,默认情况下, 其名为docker compose.yml 或docker compose.yamldocker compose up
会查找Compose文件,基于此构建镜像、网络和卷,并启动容器
-d
: daemon模式,在后台启用应用- 也可以使用
&
, 但是这样不会重定向输入输出流
- 也可以使用
列出Compose应用:
1 | docker-compose ps |
该命令作用和docker container ls
差不多
停止Compose应用
停止Compose应用, 并删除资源(类似docker container rm -f
):
1 | docker compose down |
- 该命令会停止并关闭容器,删除网络(卷和镜像不会被删除)
停止Compose应用,不删除资源:
1 | docker compose stop |
相当于docker compose stop
对于停止的Compose应用,删除其资源:
1 | docker compose rm |
类似docker compose rm
, 会删除容器和网络
重启Compose应用
对于停止的Compose应用,重新启动:
1 | docker compose restart |
类似docker compose restart
查看Compose应用运行情况
查看Compose应用运行情况:
1 | docker compose top |
Compose文件示例
我们给出一个示例:
先进入构建目录:
1 | ❯ cd ./counter-app |
查看目录内容:
1 | ❯ ls |
app.py
: 应用程序代码
文件格式
查看示例的docker compose.yml
:
1 | ❯ cat ./docker compose.yml |
一级key:
version
: 指定Compose文件格式 (注意并非compose或者docker引擎的版本号)services
: 定义不同的服务networks
: 令docker创建新的网络- ( 默认是桥接模式,这是单主机网络,只能够实现同一主机上容器的连接 )
volumns
: 令docker创建新的卷
二级key:
services
部分定义两个二级key
,docker compose会将每个服务部署为一个容器,并使用key作为容器名字的一部分,在二级key中有如下指令:build: [file_path]
:指定Dockerfile的所在目录,该Dockerfile会被用于创建镜像,进而启动容器。 如果已经存在镜像了,可以使用image <image>
image: <image>
: 指定Docker基于镜像启动容器command: [executable]
: 指定Docker容器中运行的主程序ports:- target: [target_port] published: [source_port]
: 指定端口映射, 将主机的published
端口映射到容器的target
端口networks:
: 指定容器连接到的网络, 该网络要么已经存在,要么在networks
一级key中指定, 后者会让Docker创建该网络volumes
: 指定Docker将[source]
卷挂到容器的[target]
卷, 该网络要么已经存在,要么在`volumes
:`一级key中指定depends_on: <service>
: 指定服务启动时间,但是启动时间早并不能保证后一个服务启动时前一个服务已经启动完成
解释
示例解释:
在本示例中, DockerCompose会调用Docker来为web-fe 服务部署一个独立的容器。该容器基于Compose文件位于同一目录下的Dockerfile构建的镜像。基于该镜像启动的容器会运行app.py 作为主程序,将5000端口暴露给宿主机,连接到counter-net 网络上,并挂载一个卷到/code . redis服务也类似
由于两个服务都连接到counter-net 网络,因此它们可以通过名称解析到对方的地址。了解这一点重要,本例中上层应用被配置为通过名称与Redis服务通信
查看容器:
1 | ❯ docker container ls |
可以看到每个服务都创建了对应的容器
查看网络:
1 | ❯ docker network ls |
可以看到创建了桥接网络counter-app_counter-net
查看卷:
1 | ❯ docker volume ls |
可以看到创建了卷counter-app_counter-vol
热部署
由于主机的卷被挂载到容器上,对主机上卷的改动就是对容器的卷的改动。 docker compose
可以做到热部署,就是说可以直接在主机的卷上进行修改,容器就会产生相应的改变,不需要重新部署
example:
先查看示例中卷的挂载情况:
1 | ❯ docker volume inspect counter-app_counter-vol | grep Mount |
我们先修改工作目录下的app.py
, 将其copy到/var/lib/docker/volumes/counter-app_counter-vol/_data
:
1 | do some change... |
(当然你也可以直接修改挂载点的文件, 不过由于docker compose每次从构建目录(这里是~/counter-cp/
)来构建应用,如果不改变构建目录下的文件的话,下次构建时,)
现在挂载点的文件内容变了,我们打开localhost:5000
,发现修改也生效了。 整个过程不需要重新部署