本文从本人博客搬运,原文格式更加美观,可以移步原文阅读:docker-compose容器编排
基本介绍 docker-compose
是docker官方的开源项目,负责实现对docker容器集群的快速编排。它的作用是定义和运行多个docker容器的应用
之前我们如果要启动多个容器,只能手动执行多个docker run
命令。然而在日常工作中,一个项目往往要同时启动非常多的容器,并且容器的启动顺序也有要求,例如要运行一个web项目,除了启动web服务容器之外,还需要启动它依赖的mysql、redis等等,这时候手动一个个启动非常麻烦
docker-compose
允许用户通过一个单独的docker-compose.yml
模板文件来定义一组相关联的应用容器为一个项目,它有2个重要的概念:
服务(service)
:一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。在docker-compose.yml
中定义项目(project)
:由一组关联的应用容器组成的一个完整业务单元,一个docker-compose.yml
文件就代表一个项目
docker-compose
的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。比如我们要开发一个Web项目,除了运行后端应用接口的容器,还需要依赖MySQL、Redis、RabbitMQ、Nginx等容器,那么就可以通过一个docker-compose.yml
来统一编排管理这一组容器文章图片
安装 1.linux 从官方下载编译好的
docker-compose
二进制可执行文件,下载地址为:https://github.com/docker/compose/releases下载完成后手动上传到linux指定目录
/usr/local/bin
,将其文件名修改成docker-compose
。然后给其加上可执行权限# 因为下载后的docker-compose文件是一个可执行脚本,所以要开放其权限
chmod +x /usr/local/bin/docker-compose
安装完成后可以用
docker-compose -v
检查安装是否成功文章图片
2.win/mac win/mac平台安装docker后就自带
docker-compose
,可以直接使用具体使用 1.入门 使用
docker-compose
的基本步骤如下:- 编写
docker-compose.yml
模板文件,指定要编排运行的一组容器 - 利用
docker-compose
指令启动模板文件中的所有容器
docker-compose.yml
version: "3.2"# 指定compose的版本services:
tomcat1: # 代表一个容器的服务名称,在文件中必须唯一
image: tomcat:8.0-jre8# 指定用哪个镜像来创建这个容器
ports:
- "8080:8080"# 指定容器与宿主机的端口映射
tomcat2:
image: tomcat:8.0-jre8
ports:
- "8081:8080"
把上述模板文件在独立的一个目录中创建,这里是
/docker/compose
。然后在该目录下启动模板文件中定义的容器docker-compose up
文章图片
可以发现启动时,由于镜像不存在,compose先帮我们自动下载了镜像,然后启动2个tomcat容器,并且2个容器的日志颜色会进行区分
文章图片
2.模板文件指令详解 模板文件指令指的是
docker-compose.yml
中可以写的指令。每个指令都可以类比为docker run
中的某个参数2.1 version
指的是
docker compose
的版本号,与docker的版本有对应关系:Compose file format | Docker Engine release |
---|---|
Compose specification | 19.03.0+ |
3.8 | 19.03.0+ |
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.+ |
指定运行容器的镜像名称或id,如果本地镜像不存在,compose将会尝试拉取这个镜像
2.3 ports
容器与宿主机的端口映射信息,格式为
宿主机端口:容器端口
,可以不指定宿主机端口,此时宿主机将会随机选择端口version: "3.2"services:
mytomcat:
image: tomcat:8.0-jre8
ports:
- "8081:8080"
- "8082:8082"
建议端口映射信息加上双引号,否则可能会出现一些意外错误2.4 volumes
容器与宿主机的数据卷映射。可以采用如下格式:
宿主机绝对路径:容器绝对路径
数据卷名称:容器绝对路径
,如果采用这种方式,还必须在后面声明所使用的数据卷
version: "3.2"services:
mytomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
volumes:
- tomcatwebapp:/usr/local/tomcat/webapps# 数据卷映射,如果采用数据卷名称方式,必须在下面定义数据卷名称volumes:
tomcatwebapp:# 声明上面所使用的数据卷
如果使用数据卷名称方式进行映射,那么在启动容器时,compose会自动帮我们创建一个数据卷,名称为
项目名_自定义数据卷名
,其中项目名为docker-compose.yml
模板文件所在的目录名文章图片
如果不想使用compose帮我们自动创建的这个带项目名前缀的数据卷名称,可以指定使用外部已存在的数据卷名称,但此时必须先用
docker volume create
创建出指定的数据卷,否则会报错version: "3.2"services:
mytomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
volumes:
- tomcatwebapp:/usr/local/tomcat/webapps# 数据卷映射,如果采用数据卷名称方式,必须在下面定义数据卷名称volumes:
tomcatwebapp:# 声明上面所使用的数据卷
external:
true# 使用外部已存在的数据卷tomcatwebapp,该数据卷必须存在,不存在的话必须先手动创建,否则报错
一般情况下使用compose默认帮我们创建的带项目名称前缀的数据卷即可,因为compose管理容器的单位是项目,这样能区分不同的项目2.5 networks
【#|docker-compose容器编排】配置容器使用哪个网络(桥)
version: "3.2"services:
mytomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- mynetwork# 指定容器连接哪个网络。指定的自定义网络名称必须在下面定义networks:
mynetwork:# 定义网络。定义后才能在上面使用,否则报错
启动容器后,compose会自动帮我们创建
mynetwork
网络文章图片
可以看出:
- 如果我们在模板文件中没有指定容器用的网络,那么compose会自动创建一个名称为
项目名_default
的网络,其中项目名为docker-compose.yml
模板文件所在的目录名 - 如果我们在模板文件中指定了容器的网络,那么compose会自动创建一个名称为
项目名_自定义网络名
的网络,其中项目名为docker-compose.yml
模板文件所在的目录名
docker network create
创建出指定的网络,否则会报错version: "3.2"services:
mytomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- mynetwork# 指定容器连接哪个网络。指定的自定义网络名称必须在下面定义networks:
mynetwork:# 定义网络。定义后才能在上面使用,否则报错
external:
true# 使用外部已存在的网络mynetwork,该网络必须存在,不存在的话必须先手动创建,否则报错
一般情况下使用compose默认帮我们创建的带项目名称前缀的网络即可,因为compose管理容器的单位是项目,这样能区分不同的项目2.6 container_name
指定容器的名称。不指定时默认由compose生成带项目名称前缀的容器名
version: "3.2"services:
mytomcat:
container_name: tomcat01# 指定容器的名称
image: tomcat:8.0-jre8
ports:
- "8080:8080"
文章图片
2.7 environment
设置环境变量,可以使用数组或字典两种格式。如果只给定变量名称,不指定值的话会自动获取运行compose宿主机上对应的环境变量的值,可以用来防止泄露不必要的数据
version: "3.2"services:
mysql5:
container_name: mysql01# 指定容器的名称
image: mysql:5.7
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root# 等价写法MYSQL_ROOT_PASSWORD: root
如果环境变量的名称或值中用到2.8 env_filetrue|false
或者yes|no
这样的布尔表达式,建议放到引号里,避免解析错误
从文件中获取环境变量,可以为单独的文件路径或列表
如果通过
docker-compose -f FILE
方式来指定compose.yml模板文件,则env_file
中变量的路径会基于模板文件路径如果有变量名称与
environment
指令冲突,则以后者为准# 指定单个环境变量文件
env_file: .env# 指定多个环境变量文件
env_file:
- ./common.env
- /opt/secrets.env
环境变量文件中每一行必须符合格式,支持
#
开头的注释行# mysql密码
MYSQL_ROOT_PASSWORD=root
一般我们会把一些敏感信息环境变量放到文件中,比如mysql密码。这样compose模板文件中不会暴露密码2.9 command
用于run镜像之后覆盖容器启动时的默认命令,比如启动redis时
docker run -p 6379:6379 -d --name redis5 -v redis.data:/data -v redis.conf:/etc/redis/redis.conf redis:5 redis-server /etc/redis/redis.conf
,需要如下配置version: "3.2"services:
redis5:
container_name: redis5# 指定容器的名称
image: redis:5
ports:
- "6379:6379"
volumes:
- redis.data:/data
- redis.conf:/etc/redis
command: "redis-server /etc/redis/redis.conf"# 指定容器启动时要运行的命令
2.10 depends_on
解决容器之间的依赖、启动先后问题。比如我们自己的web应用会连接mysql、redis,那么就要求mysql、redis先启动,web应用后启动
version: "3.2"services:
web:
image: mywebapp:latest
ports:
- "8080:8080"
depends_on:# 依赖于redis5和mysql5.7,会先启动redis5和mysql5.7
- redis5# 注意一定要写services下面配置的服务id,而不是容器名称
- mysql5.7redis5:
container_name: redis01
image: redis:5
ports:
- "6379:6379"
volumes:
- redis.data:/data
- /dockermapping/redis/conf/redis.conf:/etc/redis/redis.conf
command: "redis-server /etc/redis/redis.conf"# 指定容器启动时要运行的命令mysql5.7:
container_name: mysql01
image: mysql:5.7
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
2.11 build
如果要将我们自己的应用放到compose模板文件中进行编排,首先要用dockerfile生成镜像,然后在compose模板中编排,这样做稍显麻烦。build指令可以一步到位,在compose模板中将指定的dockerfile打包成镜像后再运行
version: "3.2"services:
web:
build:# 启动服务时先将build命令中指定的dockerfile打包成镜像,再运行该镜像
context: myweb# 指定上下文目录,即dockerfile所在目录
dockerfile: Dockerfile# 指定dockerfile的文件名
ports:
- "8080:8080"
depends_on:# 依赖于redis5和mysql5.7,会先启动redis5和mysql5.7
- redis5# 注意一定要写services下面配置的服务id,而不是容器名称
- mysql5.7redis5:
container_name: redis01
image: redis:5
ports:
- "6379:6379"
volumes:
- redis.data:/data
- redis.conf:/etc/redis
command: "redis-server /etc/redis/redis.conf"# 指定容器启动时要运行的命令mysql5.7:
container_name: mysql01
image: mysql:5.7
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
2.12 限制容器可用内存
version: "3.2"
services:
redis:
image: redis:alpine
container_name: testredis
deploy:
resources:
limits:
memory: 2G# 限制容器可用最大内存为2G
3.docker-compose常用命令 对于
docker-compose
来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。如果没有特别的说明,命令的对象将是项目,这意味着项目中所有的服务都会收到命令影响执行
docker-compose [具体命令] --help
或者docker-compose help [具体命令]
可以查看某个具体命令的格式。docker-compose
的基本格式如下:docker-compose [-f=...] [options] [COMMAND] [ARGS...]
命令的选项如下:
-f,--file FILE
:指定使用的compose模板配置文件,默认为docker-compose.yml
,可以多次指定-p,--project-name NAME
:指定项目名称,默认将使用模板文件所在目录名称作为项目名称--x-networking
:使用docker的可拔插网络后端特性--x-network-driver DRIVER
:指定网络后端的驱动,默认为bridge
--verbose
:输出更多调试信息-v,--version
:打印版本并退出
格式为
docker-compose up [options] [SERVICE...]
- 该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。可以说大部分的时候都可以直接通过该命令来启动一个项目
- 连接的服务将会被自动启动,除非已经处于运行状态
- 默认情况下,
docker-compose up
启动的容器都在前台,控制台将会同时打印所有容器的输出信息,方便进行调试。当通过Ctrl-C
停止命令时,所有容器将会停止。如果想要在后台启动所有容器,可以使用docker-compose up -d
,推荐生产环境使用该选项 - 默认情况下,如果服务容器已经存在,
docker-compose up
将会尝试停止容器,然后重新创建(保持使用volumes
挂载的数据卷),以保证新启动的服务匹配docker-compose.yml
文件的最新内容
mytomcatapp
目录下version: "3.2"# 指定compose的版本services:
tomcat1: # 代表一个容器的服务名称,在文件中必须唯一
image: tomcat:8.0-jre8# 指定用哪个镜像来创建这个容器
ports:
- "8080:8080"# 指定容器与宿主机的端口映射
volumes:
- webapp1:/usr/local/tomcat/webapps
tomcat2:
image: tomcat:8.0-jre8
ports:
- "8081:8080"
volumes:
- webapp2:/usr/local/tomcat/webappsvolumes:
webapp1:
webapp2:
启动时指定后台运行与项目名称
docker-compose up -d
运行后可以发现,compose帮我们自动创建了项目的网络、数据卷、容器
文章图片
此时我们尝试修改模板文件中容器的端口映射
文章图片
然后再次运行compose up指令,会发现docker-compose能判断出tomcat1没有被修改,无需重新构建启动。tomcat2重新映射新的端口启动。并且原来的网络、数据卷都还在
文章图片
如果不修改任何模板文件内容,在服务容器已经启动的情况下再次运行
docker-compose up -d
,将不会有任何效果文章图片
3.2 down
停止并删除
up
命令所启动的容器,并移除网络我们在up命令执行后执行down命令,会发现up启动的容器将被停止并删除,同时容器网络也会被删除,但是数据卷会被保留
文章图片
3.3 ps
列出项目中目前的所有容器,格式为
docker-compose ps [options] [SERVICE...]
选项:
-q
:只打印容器的id信息
文章图片
3.4 restart
重启项目中的服务,格式为
docker-compose restart [options] [SERVICE...]
选项:
-t,--timeout TIMEOUT
:指定重启前停止容器的超时,默认为10秒
删除所有停止状态的服务容器,格式为
docker-compose rm [options] [SERVICE...]
在执行该命令前推荐先执行
docker-compose stop
命令来停止容器选项:
-f,--force
:强制直接删除,包括非停止状态的容器。尽量不要用该选项-v
:删除容器所挂载的数据卷
启动已经存在的服务容器。格式为
docker-compose start [SERVICE...]
3.7 stop
停止已经处于运行状态的容器,但不删除它。通过
docker-compose start
可以再次启动这些容器选项:
-t,--timeout TIMEOUT
:停止容器时候的超时,默认为10秒
查看各个服务容器内运行的进程
文章图片
3.9 pause/unpause
暂停/恢复服务容器,格式为
docker-compose pause/unpause [SERVICE...]
文章图片
推荐阅读
- docker|Docker学习(八) -- Docker-compose容器编排
- kubernetes|升级 Kubernetes 上的 TiDB 集群
- docker|Docker 进阶指南(上)- 使用Dockerfile自定义镜像
- #|帝国竞争算法(ICA)(Matlab代码实现)
- #|智能电网中需求响应研究(Matlab代码实现)
- #|vue3下watch的使用
- #|【漏洞复现】AppWeb认证绕过漏洞(CVE-2018-8715)
- #|使用基于非支配排序的鲸鱼优化算法的生产过程中关键质量特征识别的多目标特征选择(Matlab代码实现)
- #|基于蜜蜂算法求解电力系统经济调度(Matlab代码实现)