Compose 常见问题
docker compose
和 docker-compose
有什么区别?
Docker Compose 命令行二进制文件的第一版于 2014 年首次发布。它使用 Python 编写,并使用 docker-compose
调用。通常,Compose V1 项目在 compose.yml 文件中包含一个顶级版本元素,其值范围从 2.0 到 3.8,它们指的是特定的文件格式。
Docker Compose 命令行二进制文件的第二版于 2020 年发布,它使用 Go 编写,并使用 docker compose
调用。Compose V2 忽略 compose.yml 文件中的顶级版本元素。
更多信息,请参阅 Compose 的历史和发展。
up
、run
和 start
之间有什么区别?
通常,您需要 docker compose up
。使用 up
启动或重启 compose.yml
中定义的所有服务。在默认的“附加”模式下,您可以看到所有容器的所有日志。在“分离”模式 (-d
) 下,Compose 在启动容器后退出,但容器会继续在后台运行。
docker compose run
命令用于运行“一次性”或“临时”任务。它需要您要运行的服务名称,并且只启动运行服务所依赖的服务的容器。使用 run
运行测试或执行管理任务,例如从数据卷容器中删除或添加数据。run
命令的作用类似于 docker run -ti
,因为它会打开一个与容器交互的终端,并返回与容器中进程的退出状态匹配的退出状态。
docker compose start
命令仅用于重新启动以前创建但已停止的容器。它永远不会创建新容器。
为什么我的服务需要 10 秒才能重新创建或停止?
docker compose stop
命令尝试通过发送 SIGTERM
来停止容器。然后它等待 默认超时时间 10 秒。超时后,将向容器发送 SIGKILL
以强制将其终止。如果您正在等待此超时,则表示您的容器在收到 SIGTERM
信号时没有关闭。
关于容器中 进程处理信号 的问题,已经有很多文章写过了。
要解决此问题,请尝试以下操作
确保您在 Dockerfile 中使用
CMD
和ENTRYPOINT
的 exec 形式。例如,使用
["program", "arg1", "arg2"]
而不是"program arg1 arg2"
。使用字符串形式会导致 Docker 使用bash
运行您的进程,而bash
无法正确处理信号。Compose 始终使用 JSON 形式,因此如果您在 Compose 文件中覆盖命令或入口点,则不必担心。如果可以,请修改您正在运行的应用程序,以便为
SIGTERM
添加显式信号处理程序。将
stop_signal
设置为应用程序知道如何处理的信号services: web: build: . stop_signal: SIGINT
如果无法修改应用程序,请使用轻量级初始化系统(例如 s6)或信号代理(例如 dumb-init 或 tini)。这些包装器中的任何一个都可以正确处理
SIGTERM
信号。
如何在同一主机上运行 Compose 文件的多个副本?
Compose 使用项目名称为项目的所有容器和其他资源创建唯一标识符。要运行项目的多个副本,请使用-p
命令行选项或COMPOSE_PROJECT_NAME
环境变量设置自定义项目名称。
我可以使用 JSON 而不是 YAML 作为我的 Compose 文件吗?
是的。YAML 是 JSON 的超集,因此任何JSON文件都应该是有效的YAML文件。要将JSON文件与Compose一起使用,请指定要使用的文件名,例如
$ docker compose -f docker-compose.json up
我应该使用 COPY
/ADD
或卷包含我的代码吗?
您可以使用Dockerfile
中的COPY
或ADD
指令将代码添加到镜像中。如果您需要将代码与Docker镜像一起重新定位,例如将代码发送到另一个环境(生产、CI等)时,这将非常有用。
如果您想更改代码并立即看到更改效果,例如在开发代码时并且您的服务器支持热代码重载或实时重载,请使用volume
。
在某些情况下,您可能希望同时使用两者。您可以使用COPY
让镜像包含代码,并在您的Compose文件中使用volume
包含来自主机端的代码(在开发期间)。卷会覆盖镜像的目录内容。