学习 Docker(6)-Docker Compose
简介
Compose
项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。Compose 可以使用 YAML 文件来配置应用程序的服务,然后可以从配置中使用单个命令,创建并启动所有服务。
Compose
中有两个重要的概念:
- 服务 (
service
):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。 - 项目 (
project
):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml
文件中定义。
Compose
项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用 Compose
来进行编排管理。
docker-compose.yaml
docker-compose.yaml
和 docker-compose.yml
是 Docker Compose 的默认模版文件名称,格式为 YAML 格式。模板文件是使用 Compose
的核心。模版文件中使用的指令,与 Dockerfile 中的指令有相似之处。
docker-compose.yaml
中的配置为创建容器时的配置,Dockerfile 中的配置为创建镜像时的配置。
一般我们在第一行使用 version
声明模版文件使用的版本。
build 和 image
docker-compose 中的每个服务都必须通过 image
指令指定镜像或者 build
指令指定 Dockerfile 来自动构建生成镜像。
使用 build 指令时,要指定 Dockerfile
所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径
)。Compose
将会利用它自动构建这个镜像,然后使用这个镜像。
使用 image 指令时,如果本地不存在,会自动尝试拉取镜像。
|
|
上述指令含义为,mysql 服务使用 mysql:5.7 镜像,webapp 服务使用 ./dir
目录下的 Dockerfile 文件构建镜像。
depends_on
指定服务的依赖。服务启动时,必须先启动其依赖的其他服务。也就是说:
- 被依赖的服务会先启动;
- 启动当前服务时,也会启动其依赖的服务。
举例,celery 的服务依赖于 rabbitmq 服务和 redis 服务。
|
|
environment
设置运行时的环境变量。可以使用 YAML 语法的数组格式或者字典格式。
|
|
如果只定义环境变量名而不赋值,则从执行模版文件所在的 shell 环境变量中,或者从模版文件所在目录的 .env
文件中读取(模版文件执行时,会自动读取当前目录的 .env
环境变量文件),前者优先级较高。
|
|
另外要注意的是,变量值中用到的表达布尔含义的词语,需要放到引号里,避免 YAML 自动解析某些内容为对应的布尔语义。这些词有:
|
|
env_file
从文件中获取环境变量。文件路径相对于模版文件路径。
|
|
如果有变量名称与 environment 指令冲突,则以 environment 指令为准。
volumes
设置目录映射或数据卷挂载。格式可以为 HOST:CONTAINER
、HOST:CONTAINER:MODE
或 DATA_VOLUME:CONTAINER
,模式可以为:ro
只读,rw
读写。
宿主机路径可以指定相对路径,注意指定相对路径时,路径要写完整,否则可能被认为是数据卷。
|
|
上述第一个是绝对路径映射,第二个是相对路径映射,第三个是挂载名为 ui 的数据卷。
另外如果宿主机路径指向的是一个已存在的文件,则会映射文件到容器中,而不是目录。例如映射 mysql 的配置文件。
|
|
networks
配置容器连接的网络。为增强安全性,我们可以给应用指定不同的网络以隔离它们。网络需要在根层级声明和配置。
举例,我们有一个 web 应用,包含 web、nginx 和 mysql 三个服务。我们可以配置两个网络:后端 back-tire 和 前端 front-tire。其中 web 和 nginx 通信使用 front-tire,web 和 mysql 通信使用 back-tire,这样就将 nginx 和 mysql 隔离开来。
|
|
ports 和 expose
ports 指定容器端口到宿主机的映射。expose 只暴露端口供容器间通过网络访问,不映射到宿主机(不 expose 在同一网络中也是能够互相访问的)。
expose 指定暴露的端口就可以。
ports 映射有几种格式:
- 只指定容器端口,映射到宿主机随机端口;
- 指定宿主机端口和容器端口
HOST:CONTAINER
,则映射到指定端口并监听0.0.0.0
; - 指定宿主机监听地址、宿主机端口和容器端口
IP:HOST:CONTAINER
。
|
|
working_dir
指定容器中工作目录,等同于 Dockerfile 中的 WORKDIR。
|
|
command
覆盖容器启动后默认执行的命令。
|
|
restart
指定容器退出后的重启策略。
|
|
有四种取值:
no
默认值,退出后不重启;on-failure
出错退出(exit code 不为 0)时重启。unless-stoped
除非显式停止或停止或重新启动 Docker 本身,否则重新启动容器。always
总是重启;
生产环境可以适当设置为 on-failure
或者 unless-stoped
。对于一些特殊应用,例如 ss,可以设置为 always
。
注意:
- 重启策略仅在容器成功启动后生效。在这种情况下,成功启动意味着容器启动至少 10 秒并且 Docker 已开始监视它。这可以防止根本不启动的容器进入重启循环。
- 如果手动停止容器,则会忽略其重新启动策略,直到 Docker 守护程序重新启动或手动重新启动容器。这是防止重启循环的另一种尝试。
CLI 命令
config
验证 Compose 文件格式是否正确,若正确则显示配置,若格式错误显示错误原因。
build
构建(重新构建)项目中的服务镜像。
|
|
start
启动已经存在的服务容器。
|
|
stop
停止已经处于运行状态的容器,但不删除它。通过 docker-compose start
可以再次启动这些容器。
|
|
选项:
-t, --timeout TIMEOUT
停止容器时候的超时(默认为 10 秒)。
restart
重启项目中的服务。
|
|
选项:
-t, --timeout TIMEOUT
指定重启前停止容器的超时(默认为 10 秒)。
rm
删除所有(停止状态的)服务容器。推荐先执行 docker-compose stop
命令来停止容器。
|
|
选项:
-f, --force
强制直接删除,包括非停止状态的容器。一般尽量不要使用该选项。-v
删除容器所挂载的数据卷。
up
该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。
|
|
选项:
-d
在后台运行服务容器。--no-color
不使用颜色来区分不同的服务的控制台输出。--no-deps
不启动服务所链接的容器。--force-recreate
强制重新创建容器,不能与--no-recreate
同时使用。--no-recreate
如果容器已经存在了,则不重新创建,不能与--force-recreate
同时使用。--no-build
不自动构建缺失的服务镜像。-t, --timeout TIMEOUT
停止容器时候的超时(默认为 10 秒)。
如果 docker-compose.yaml 指定的环境变量发生改变,例如 environment 发生改变,或 env_file 指向的文件内容发生改变,up 命令执行时会重新创建容器。
logs
查看服务容器的输出。
|
|
默认情况下,docker-compose 将对不同的服务输出使用不同的颜色来区分。可以通过 --no-color
来关闭颜色。
该命令在调试问题的时候十分有用。
FAQ
如何设置容器的时区
容器默认的时区为 UTC 时区,要设置为不同时区只需要在模版文件中设置 TZ
环境变量即可:
|
|