Compose 常见问题

docker composedocker-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的历史与发展

uprunstart 之间有什么区别?

通常,您会想要使用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中使用的是CMDENTRYPOINT的exec形式。

    例如使用 ["program", "arg1", "arg2"] 而不是 "program arg1 arg2"。 使用字符串形式会导致 Docker 使用 bash 运行你的进程,这不会正确处理信号。Compose 总是使用 JSON 形式,所以如果你在 Compose 文件中覆盖了命令或入口点,不用担心。

  • 如果可能,修改你正在运行的应用程序,为SIGTERM添加一个明确的信号处理程序。

  • stop_signal设置为应用程序知道如何处理的信号:

    services:
      web:
        build: .
        stop_signal: SIGINT
  • 如果你无法修改应用程序,可以将应用程序包装在一个轻量级的初始化系统(如 s6)或信号代理(如 dumb-inittini)中。这些包装器中的任何一个都会负责正确处理 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中的COPYADD指令将代码添加到镜像中。如果你需要将代码与Docker镜像一起迁移,例如将代码发送到另一个环境(生产、CI等),这将非常有用。

如果你想对代码进行更改并立即看到更改反映出来,例如在开发代码时,你的服务器支持热代码重载或实时重载,请使用volume

在某些情况下,您可能希望同时使用两者。您可以使用COPY将代码包含在镜像中,并在开发期间使用Compose文件中的volume从主机包含代码。卷会覆盖镜像中的目录内容。