通过前面两篇的学习,我们可以通过 Dockerfile
文件让用户很方便的定义一个单独的应用容器。
然后,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。
开发一个 web应用
,除了web服务器本身,还需要数据库容器、缓存容器、可能还需要一些负载均衡容器等等。
Docker-compose 介绍
Docker compose
恰好满足这样的需求,它是用于「定义和运行多容器 Docker 应用程序」
的工具。
通过Compose,我们可以使用YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
Docker compose 使用的三个步骤:
-
使用
Dockerfile
文件定义应用程序的环境 -
使用 docker compose 编排所有服务
-
最后使用
docker-compose up(v1)
或者docker compose up(v2)
进行创建并启动所有服务。
Docker compose 中的概念:
-
服务(service): 一个应用容器, 实际上可以包括若干运行相同镜像的容器实例。
-
项目(project): 由一组关联的应用容器组成的一个完整的业务单元, 在
docker-compose 中定义
docker-compose.yml 文件详解
Docker compose 允许用户通过 docker-compose.yml 文件来定义一组相关联的容器为一个工程。
模板文件是使用 Compose
的核心,涉及很多指令关键字。
version
描述 Compose 文件的版本信息,当前最新版本为 3.8,对应的 Docker 版本为 19.03.0+。关于每个版本的详细信息请参考:https://docs.docker.com/compose/compose-file/compose-versioning/
以下为 Compose 文件的版本信息所对应的 Docker 版本。
services
services
用来定义服务,可以多个,每个服务中定义了创建容器时所需要的镜像、参数、依赖等,就像将命令行参数传递给 docker run
一样。
使用docker run 构建一个MySQL容器:
docker run -di --name think_mysql8 -p 3306:3306 -v /mydata/mysql/conf:/etc/mysql/conf.d -v /mydata/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:8
使用 docker-compose.yml
定义为:
# 描述 compose 文件的版本
version: "3.8"
# 定义服务,可以多个
services:
# 服务名
mysql:
# 所使用的镜像
image: mysql:8
# 容器名称
container_name: think_mysql8
# 宿主机和容器的端口映射关系
ports:
- "3306:3306"
# 创建容器需要的环境变量
MYSQL_ROOT_PASSWORD: 123456
# 挂载卷
- "/mydata/mysql/conf:/etc/mysql/conf.d"
- "/mydata/mysql/data:/var/lib/mysql"
image
指定创建容器时所需要的 镜像名称tag
或者 镜像ID
, 镜像本地不存在, 则会去docker hub 上进行拉取
services:
nginx:
image: nginx:latest
build
基于 Dockerfile
文件进行构建, 在使用 docker-compose up
时会进行构建。
通过 build
配置项可以指定 Dockerfile
所在文件夹的路径。Compose
将会利用 Dockerfile
自动构建镜像,然后使用镜像启动服务容器。
# 绝对路径,在该路径下基于名称为 Dockerfile 的文件构建镜像
/var/data/my-docker
# 相对路径,相对当前 docker-compose.yml 文件所在目录,基于名称为 Dockerfile 的文件构建镜像
.
version: "3.8"
services:
webapp:
build: ./dir
使用context指令
指定dockerfile所在文件夹的路径, 也可以是远程 Git 仓库的 URL
使用dockerfile指令
指定dockerfile文件名
使用arg指令
指定构建镜像时的变量
。
version: "3.8"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-web
args:
buildno: 1
container_name
Compose 创建的容器默认生成的名称格式为: 工程名称_服务名称_序号
, 想使用自定义名称的话, 使用 container_name
关键字声明。
services:
webapp:
container_name: think/webapp
depends_on
一般项目容器启动顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。
例如,在没有启动数据库容器而启动了web容器,web容器因找不到数据库而退出。
depends_on 就是解决容器依赖,启动先后顺序
的问题。
version:"3.8"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: mysql
这时会先启动 db, redis 在启动 web 服务。
ports
容器对外暴露的端口, 映射到宿主机上。
使用宿主端口:容器端口 (HOST:CONTAINER)
格式,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。
ports:
- "80:80"
- "3306:3306"
tips:当使用 HOST:CONTAINER
格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 YAML
会自动解析 xx:yy
这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。
expose
容器暴露的端口不映射到宿主机, 只允许能被连接的服务访问。
expose:
- "80"
- "8080"
restart
容器重启策略,简单理解就是 Docker 重启以后容器要不要一起启动
。配置有以下几种方式:
-
no
: 默认的重启策略,在任何情况下都不会重启容器; -
no-failure
:容器非正常退出时,才会重启容器; -
always
: 容器总是重新启动,即使容器被手动停止了, 当Docker重启时容器也会一起启动。 -
unless-stopped
: 容器总是重新启动, 除非容器被停止(手动或者其他方式), 那么Docker 重启时则不会启动。
services:
nginx:
image: nginx
container_name: mynginx
ports:
- "80:80"
restart: always
environment
环境变量。可以使用数组或者字典,布尔相关的值都需要使用引号括起来,包括以下:
y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF
确保YAML解析器不会将他们转换为真或假。
# 第一种方式
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
# 第二种方式
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
env_file
从文件中获取环境变量, 可以指定一个或多个文件,优先级低于environment
指定的环境变量。
evn_file:
- /var/php.env # 绝对路径
- ./php.env # 相对路径, 相对当前 docker-compose.yml 文件所在目录
- ./apps/mysql.env # 相对路径, 相对当前 docker-compose.yml 文件所在目录
tips: env文件的每一行采用 键=值
的方式。以 # 开头的行会被视为注释并被忽略。空行也会被忽略。
volumes
数据卷所挂载路径设置。数据卷,用于实现目录挂载,支持「指定目录挂载」、「匿名挂载」、「具名挂载」
。
-
指定目录挂载
: 宿主机目录 : 容器目录 : 读写权限(可省略) -
匿名挂载
: 容器目录:读写权限(可忽略) -
具名挂载
: 数据卷条目名称:容器目录:读写权限(可忽略)
version: "3.8"
# 定义服务,可以多个
services:
mysql: # 服务名称
image: mysql:8 # 创建容器时所需的镜像
container_name: mysql8 # 容器名称,默认为"工程名称_服务条目名称_序号"
ports: # 宿主机与容器的端口映射关系
- "3306:3306" # 左边宿主机端口:右边容器端口
environment: # 创建容器时所需的环境变量
MYSQL_ROOT_PASSWORD: 1234
volumes:
# 绝对路径
- "/mydata/docker/data:/var/lib/mysql"
# 相对路径,相对当前 docker-compose.yml 文件所在目录
- “./conf:/etc/mysql/conf.d“
# 匿名挂载,匿名挂载只需要写容器目录即可,容器外对应的目录会在 /var/lib/docker/volume 中生成
- "/var/lib/mysql"
# 具名挂载,就是给数据卷起了个名字,容器外对应的目录会在 /var/lib/docker/volume 中生成
- "mysql-data-volume:/var/lib/mysql"
# 定义数据卷,可以多个
volumes:
mysql-data-volume: # 一个具体数据卷的条目名称
name: mysql-data-volume # 数据卷名称,默认为"工程名称_数据卷条目名称"
network_mode
设置网络模式, 类似 docker run 时添加的参数 –net host 或者 –network host 的用法。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
networks
配置容器连接的网络,引用顶级 networks 下的条目。
# 定义服务,可以多个
services:
nginx: # 服务名称
networks: # 配置容器连接的网络,引用顶级 networks 下的条目
- nginx-net # 一个具体网络的条目名称
# 定义网络,可以多个。如果不声明,默认会创建一个网络名称为"工程名称_default"的 bridge 网络
networks:
nginx-net: # 一个具体网络的条目名称
name: nginx-net # 网络名称,默认为"工程名称_网络条目名称"
driver: bridge # 网络模式,默认为 bridge
compose 命令详解
V1版本: docker-compose [-f <arg> ...] [options] [command] [args...]
V2版本: docker compose [-f <arg> ...] [options] [command] [args...]
-
-f, –file: 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定,指定多个 yml;
-
-p, –project-name:指定工程名称,默认使用 docker-compose.yml 文件所在目录的名称;
-
-v:打印版本并退出;
-
–log-level:定义日志等级(DEBUG, INFO, WARNING, ERROR, CRITICAL)。
config
验证 docker-compose.yml 文件是否正确, 正确时不输出任何内容; 错误时,输出错误信息。
docker compose config -q
pull
docker-compose pull 拉取服务依赖的镜像。
# 拉取工程中所有服务依赖的镜像
docker-compose pull
# 拉取工程中 nginx 服务依赖的镜像
docker-compose pull nginx
# 拉取镜像过程中不打印拉取进度信息
docker-compose pull -q
up
docker-compose up 创建并启动所有服务的容器。指定多个 yml 加 -f 选项。以守护进程模式运行加 -d 选项。
# 前台启动
docker-compose up
# 后台启动
docker-compose up -d
# -f 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定,指定多个 yml
docker-compose -f docker-compose.yml up -d
logs
docker-compose logs 查看服务容器的输出日志。默认情况下,docker-compose 将对不同的服务输出使用不同的颜色来区分。可以通过 –no-color 来关闭颜色。
# 输出日志,不同的服务输出使用不同的颜色来区分
docker-compose logs
# 跟踪日志输出
docker-compose logs -f
# 关闭颜色
docker-compose logs --no-color
exec
docker-compose exec 进入服务容器。
# 进入工程中指定服务的容器
docker-compose exec nginx bash
# 当一个服务拥有多个容器时,可通过 --index 参数进入到该服务下的任何容器
docker-compose exec --index=1 nginx bash
pause
docker-compose pause 暂停服务容器。
# 暂停工程中所有服务的容器
docker-compose pause
# 暂停工程中指定服务的容器
docker-compose pause nginx
unpause
docker-compose unpause 恢复服务容器。
# 恢复工程中所有服务的容器
docker-compose unpause
# 恢复工程中指定服务的容器
docker-compose unpause nginx
restart
docker-compose restart 重启服务容器。
# 重启工程中所有服务的容器
docker-compose restart
# 重启工程中指定服务的容器
docker-compose restart nginx
start
docker-compose start 启动服务容器。
# 启动工程中所有服务的容器
docker-compose start
# 启动工程中指定服务的容器
docker-compose start nginx
stop
docker-compose stop 停止服务容器。
# 停止工程中所有服务的容器
docker-compose stop
# 停止工程中指定服务的容器
docker-compose stop nginx
kill
docker-compose kill 通过发送 SIGKILL 信号停止指定服务的容器。
# 通过发送 SIGKILL 信号停止工程中指定服务的容器
docker-compose kill nginx
rm
docker-compose rm 删除服务(停止状态)容器。
# 删除所有(停止状态)服务的容器
docker-compose rm
# 先停止所有服务的容器,再删除所有服务的容器
docker-compose rm -s
# 不询问是否删除,直接删除
docker-compose rm -f
# 删除服务容器挂载的数据卷
docker-compose rm -v
# 删除工程中指定服务的容器
docker-compose rm -sv nginx
images
docker-compose images 打印服务容器所对应的镜像。
# 打印所有服务的容器所对应的镜像
docker-compose images
# 打印指定服务的容器所对应的镜像
docker-compose images nginx
port
docker-compose port 打印指定服务容器的某个端口所映射的宿主机端口。
[root@localhost docker-nginx]# docker-compose port nginx 80
0.0.0.0:80
top
docker-compose top 显示正在运行的进程。
# 显示工程中所有服务的容器正在运行的进程
docker-compose top
# 显示工程中指定服务的容器正在运行的进程
docker-compose top nginx
docker的运行原理,会在下一篇文章中输出,欢迎各位大佬评论留言讨论。
如果我的文章对你有所帮助,还请帮忙点赞、在看、转发一下,你的支持会激励我继续坚持下去,非常感谢!
你还可以把我的公众号设为「星标」
,这样当公众号文章更新时,你会在第一时间收到推送消息,避免错过我的文章更新。
原文始发于微信公众号(白砂):Docker学习之docker-compose详解
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/19988.html