"docker compose" 和 "docker-compose" 之间的区别是什么?

380

注意:此问题是在 Docker 文档更新之前创建的(这也是它们被更新的原因 - 请参见this答案)。请不要发布指出差异文档的答案 :-)


我一直在使用docker-compose,但是注意到还有一个没有破折号的docker compose
通过谷歌搜索,我无法快速确定这两种形式之间的区别。

有人知道吗?

docker compose的帮助:

enter image description here

docker-compose 的帮助信息:

enter image description here


2
docker composedocker 可执行文件的 compose 子命令(该列表 https://docs.docker.com/engine/reference/commandline/docker/ 中不存在)。docker-compose 是一个独立的可执行文件:https://docs.docker.com/compose/reference/overview/。 - jonrsharpe
@jonrsharpe:你所说的子命令是什么意思?它不应该在这里列出吗(https://docs.docker.com/engine/reference/commandline/docker/)? - Veverke
1
我的意思是通常所说的子命令,例如请参见 https://unix.stackexchange.com/q/637840 - jonrsharpe
74
我不认为这个应该被踩。这是一个合法的问题,因为在发帖者的终端中,“docker compose”似乎是一个有效的命令。 - DannyB
3
顺便说一下,我倾向于认为JonrSharpe是正确的。如果是这样的话,我已经向docker文档提交了一个git docker请求,询问为什么compose子命令没有列在子命令文档中。让我们看看回应是什么。 - Veverke
8
谢谢您发布这篇文章。这让我有些迷惑。Docker的文档写得不是很清楚。 - waltmagic
7个回答

279
docker compose(有空格)是将compose迁移到Go语言的docker项目中的较新项目。这是docker/compose仓库的v2分支。它首先向Docker桌面用户介绍,因此Linux上的docker用户没有看到该命令。除了迁移到Go语言外,它还使用了compose-spec,并且重写的一部分可能导致行为差异。
原始的Python项目称为docker-compose,也就是docker/compose仓库的v1版本,现已被弃用,并且开发工作已转移到v2版本。要在Linux上将v2 docker compose安装为CLI插件,受支持的发行版现在可以安装docker-compose-plugin软件包。例如,在Debian上,我运行apt-get install docker-compose-plugin
更新:自从提出这个问题以来,Docker已经更新了Linux安装,包括compose v2,并且docker-compose v1不太可能再接收到任何更新。

43
请使用Docker Compose(新版本)代替docker-compose(旧版本)。https://docs.docker.com/compose/#compose-v2-and-the-new-docker-compose-command - Russo
在 Arch Linux 上,我只需要更新以下命令:sudo pacman -S docker - Robin

37
Brandon Mitchell来自docker的Captain计划回复我在github上开的问题如下:

docker/compose-cli项目处于一个中间状态,它在docker-cli Linux软件包的上游版本中不可用,但已包含在Docker Desktop中。文档页面通常遵循docker/cli中的内容,因此提前将其发布到Desktop会使文档处于困境。我将与Docker团队讨论此问题,看他们如何处理。

更新:来自docker的github问题

gtardif于2天前发表评论

compose命令参考文档现已上线

新的 docker compose 命令参考


8
直到昨天我才意识到BMitch和Brandon Mitchell是同一个人=] - Veverke
5
谢谢!我刚在一台新机器上安装了最新的Docker引擎,并运行了很多docker-compose命令,现在这些命令失败了。我发现设置一个新命令的别名是有用的: alias docker-compose='docker compose' - i01573

6
除了已经在这里说过的内容,我注意到两者之间有一个重要的区别。
在我们的设置中,`docker-compose.yml`文件位于一个模板文件夹中。这样,我们可以基于相同的模板运行同一项目的多个实例。本地实例有自己的文件夹和自己的`.env`文件(以及自己的卷)。
模板文件夹中还有一个模板`.env`文件:通过脚本复制并适应到实例文件夹中。
为了正常工作,`docker-compose.yml`文件在模板文件夹中看起来像这样:
version: "3"

services:

  wordpress:
    image: wordpress
    container_name: "${COMPOSE_PROJECT_NAME}_wordpress"
    env_file:
      - ${PWD}/.env
 ...

和本地实例 .env 文件:

# compose file location
COMPOSE_FILE=../templateFolder/docker-compose.yml

# this instance name
COMPOSE_PROJECT_NAME=foo

在这个上下文中:
- 使用 `docker-compose`,`.env` 文件被读取为实例位置,这是预期的。 - 使用 `docker compose`,`.env` 文件被读取为模板位置!
为了覆盖这个行为,我们不得不将模板的 `.env` 文件重命名为 `dotEnv`。
这个行为在这里被轻微描述:https://docs.docker.com/compose/features-uses/#have-multiple-isolated-environments-on-a-single-host
供后人参考,该轻微描述如下:
Compose 使用项目名称来隔离彼此的环境... 默认项目名称是项目目录的基本名称... 默认项目目录是 Compose 文件的基本目录。可以使用 --project-directory 命令行选项定义其自定义值。

抱歉,我没听懂。在您的服务“wordpress”的定义中,您将“env_file”定义为使用环境变量定义的路径。那个变量PWD包含相对路径还是绝对路径? - MDickten
一个绝对的路径。$PWD 提供当前路径,并由您当前的 shell 定义。 - M-Jack
这不是 pwd 而是 PWD。据我所知,在 docker-compose.yml 中无法调用 shell 函数。全大写字母表明它是一个环境变量。-- 编辑:好的,我尝试了一下,它确实可以工作。在这种情况下,我无法想象为什么 .env 文件会从不同的目录中获取。它的值将取决于 docker[-]compose 的调用位置,不是吗? - MDickten

6

引用自 https://docs.docker.com/compose/#compose-v2-and-the-new-docker-compose-command

注:该链接为英文原文,需要进行翻译。
Compose V2 and the new docker compose command
    Important
    The new Compose V2, 
which supports the compose command as part of the Docker CLI, is now available.

    Compose V2 integrates compose functions into the Docker platform, 
continuing to support most of the previous docker-compose features and flags. 
You can run Compose V2 by replacing the hyphen (-) with a space, 
using docker compose, instead of docker-compose.

1
这是根据上述提到的Github问题创建的。 - Veverke

5
如果docker安装中还没有包含docker compose,则可以将其作为CLI插件安装在Linux上。
COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | jq -r '.tag_name')

DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/$COMPOSE_VERSION/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

请查看https://docs.docker.com/compose/cli-command/#installing-compose-v2


自2021年3月起,它已经与Docker一起安装在大多数发行版中。 - Theodore R. Smith

5

如果您不想进行更改,但希望保留原始的遗留docker-compose功能,也称为Compose独立版与Compose插件版,则可以执行以下操作:

# Run as root
VERSION=v2.12.2
curl -SL https://github.com/docker/compose/releases/download/$VERSION/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
chmod a+x /usr/local/bin/docker-compose

# Test it
docker-compose

这允许您在shell脚本中继续使用docker-compose等工具。

在此页面上检查版本


3
为了从v1平稳过渡到v2,建议安装以下内容: https://github.com/docker/compose-switch 对我来说很管用。 - snorri

2

两者之间的另一个显著区别是如何生成Docker镜像标签。对于这两个命令,镜像标签是由COMPOSE_PROJECT_NAME环境变量(如果未设置,则为项目目录名称)和compose文件中的name值连接而成。对于旧版的docker-compose命令,名称将附加到带有下划线的COMPOSE_PROJECT_NAME后面,但新版的docker compose命令会使用连字符/破折号-将两者连接起来。

考虑compose文件:

services:
  web:
    build: ./webapp

假设这个组合文件存在于目录my_proj中,构建命令将生成不同的镜像标签。 docker-compose build web将生成docker.io/library/my_proj_web docker compose build web将生成docker.io/library/my_proj-web

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接