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
如果你无法修改应用程序,请使用轻量级 init 系统(如 s6) 或信号代理(如 dumb-init 或 tini)。这两个包装器都会处理
SIGTERM
。
如何在同一主机上运行 Compose 文件的多个副本?
Compose 使用项目名称为项目的所有容器和其他资源创建唯一的标识符。要运行项目的多个副本,请使用 -p
命令行选项 或 COMPOSE_PROJECT_NAME
环境变量 设置自定义项目名称。
可以使用 JSON 代替 YAML 来创建我的 Compose 文件吗?
可以。YAML 是 JSON 的超集,因此任何 JSON 文件都应该是有效的 YAML。要使用 Compose 中的 JSON 文件,请指定要使用的文件名,例如
$ docker compose -f docker-compose.json up
应该使用 COPY
/ADD
还是卷来包含我的代码?
可以使用 Dockerfile
中的 COPY
或 ADD
指令将代码添加到镜像中。如果需要将代码与 Docker 镜像一起重新定位,例如将代码发送到另一个环境(生产、CI 等),这很有用。
如果要更改代码并立即看到更改的结果,例如在开发代码时服务器支持热代码重新加载或实时重新加载,请使用 volume
。
可能存在需要同时使用这两种方式的情况。可以使用 COPY
将代码包含在镜像中,并在 Compose 文件中使用 volume
在开发期间包含来自主机的代码。卷会覆盖镜像的目录内容。