335

Note: this question was created BEFORE docker docs were updated (it was the reason they were updated - see this answer). Please do not post answers pointing out the docs on the differences :-)


I have been using docker-compose, but noticed there is also a docker compose (without the dash).
I have not been able to quickly determine the differences between the two forms by googling.

Anyone?

docker compose's help:

enter image description here

docker-compose's help:

enter image description here

Veverke
  • 9,208
  • 4
  • 51
  • 95
  • 2
    `docker compose` is the `compose` sub-command of the `docker` executable (which doesn't exist in this list https://docs.docker.com/engine/reference/commandline/docker/). `docker-compose` is a separate executable: https://docs.docker.com/compose/reference/overview/. – jonrsharpe Mar 07 '21 at 08:25
  • @jonrsharpe: what do you mean by sub-command ? Was it not supposed to be listed [here](https://docs.docker.com/engine/reference/commandline/docker/) ? – Veverke Mar 07 '21 at 08:27
  • 1
    I mean what is generally meant by a sub-command, see e.g. https://unix.stackexchange.com/q/637840 – jonrsharpe Mar 07 '21 at 08:29
  • 66
    I don't think this should have been downvoted. It is a legitimate question, since it seems like "docker compose" is a valid command in the OPs terminal. – DannyB Mar 07 '21 at 10:36
  • 3
    By the way, I am inclined to think JonrSharpe is correct. If so, however, I pushed a [git docker request](https://github.com/docker/docker.github.io/issues/12454) to docker docs asking why is the `compose` sub command not listed in the child commands doc. Let's see what the response is. – Veverke Mar 07 '21 at 10:53
  • 7
    Thanks for posting this. This through me off. Docker's documentation is muddy. – waltmagic May 21 '22 at 06:14

7 Answers7

253

The docker compose (with a space) is a newer project to migrate compose to Go with the rest of the docker project. This is the v2 branch of the docker/compose repo. It's been first introduced to Docker Desktop users, so docker users on Linux didn't see the command. In addition to migrating to Go, it uses the compose-spec, and part of the rewrite may result in behavior differences.

The original python project, called docker-compose, aka v1 of docker/compose repo, has now been deprecated and development has moved over to v2. To install the v2 docker compose as a CLI plugin on Linux, supported distribution can now install the docker-compose-plugin package. E.g. on debian, I run apt-get install docker-compose-plugin.


Update: since this question was asked, Linux installs have been updated by Docker to include compose v2 and docker-compose v1 is unlikely to receive any more updates.

Veverke
  • 9,208
  • 4
  • 51
  • 95
BMitch
  • 231,797
  • 42
  • 475
  • 450
  • 37
    use docker compose(newer version), instead of docker-compose(old version) https://docs.docker.com/compose/#compose-v2-and-the-new-docker-compose-command – Russo May 26 '22 at 08:31
  • On Arch Linux i just had to update `sudo pacman -S docker` – Robin May 28 '23 at 13:53
33

Brandon Mitchell from docker's Captain Program replied to the github issue I opened on this as follows:

The docker/compose-cli project is in an in-between state, where it's not available in upstream releases of the docker-cli Linux packages, but is being included in Docker Desktop. The documentation pages normally follow what's in the docker/cli, so having this released to Desktop early puts the documentation in a difficult position. I'm going to raise this issue with the Docker team to see how they'd like to handle it.

Update: from docker github issue:

gtardif commented 2 days ago

compose command reference doc is now live

new docker-compose command reference

Veverke
  • 9,208
  • 4
  • 51
  • 95
  • 8
    Only yesterday did I realize BMitch and Brandon Mitchell are the same =] – Veverke Mar 10 '21 at 08:29
  • 5
    Thanks for this! I've just installed the latest Docker Engine on a new machine and had a lot of commands running with `docker-compose`, which now fail. I found it useful to setup an alias for the new command: `alias docker-compose='docker compose'`. – i01573 Oct 13 '22 at 09:24
6

Quote from 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.
Russo
  • 2,186
  • 2
  • 26
  • 42
5

In addition to what has been already said here, I have noticed an important difference between the two.

In our setup, the docker-compose.yml file is located in a template folder. This way we can run multiple instances of the same project based on the same template. The local instance has its own folder with its own .env file (and also its own volumes).

There is also a template .env file in the template folder : copied and adapted to the instance folder using a script.

In order to work, the docker-compose.yml file looks like this, in the template folder :

version: "3"

services:

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

And the local instance .env file :

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

# this instance name
COMPOSE_PROJECT_NAME=foo

In this context :

  • with docker-compose, the .env file is read in the instance location, which is expected
  • with docker compose, the .env file is read in the template location !

To override this, we had to rename the template .env file into dotEnv.

This behavior is very lightly described here : https://docs.docker.com/compose/features-uses/#have-multiple-isolated-environments-on-a-single-host.

For posterity, the light description is:

Compose uses a project name to isolate environments from each other. ...

The default project name is the basename of the project directory. ...

The default project directory is the base directory of the Compose file. A custom value for it can be defined with the --project-directory command line option.

Erick G. Hagstrom
  • 4,873
  • 1
  • 24
  • 38
M-Jack
  • 293
  • 5
  • 14
  • Sorry, I didn't get that. In the definition of your service `wordpress` you've defined `env_file` as a path defined with the aid of an environment variable. Does that variable PWD contain a relative or an absolute path? – MDickten Jan 10 '23 at 10:58
  • An absolute one. `$PWD` provides the current path and is defined by your current sheel. – M-Jack Jan 10 '23 at 14:04
  • This isn't `pwd` but `PWD`. As far as I know it's not possible to call a shell function in a docker-compose.yml. The all-caps suggests it's an env var. -- EDIT: all right, I tried it and it worked. Learned sth new here. In that case, I can't imagine why the .env-File would be taken from different directories. Its value would be dependent on where the docker[-]compose was called, wouldn't it? – MDickten Jan 10 '23 at 14:17
4

If it not yet included in the docker installation, docker compose can be installed on Linux as CLI plugin.

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

See https://docs.docker.com/compose/cli-command/#installing-compose-v2

Janux
  • 841
  • 1
  • 9
  • 19
3

If you do not want to have changes, but desire the original legacy docker-compose functionality, also known as Compose standalone vs. Compose plugin, you can do the following:

# 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

This allows you to e.g. keep using docker-compose in shell scripts.

Check versions on this page.

Mikko Ohtamaa
  • 82,057
  • 50
  • 264
  • 435
  • 2
    For a smooth transition from v1 to v2 it is recommended to install this: https://github.com/docker/compose-switch works for me. – snorri Feb 17 '23 at 14:13
2

Another notable difference between the two is how the docker image tags are generated. For both commands, the image tag is concatenation of COMPOSE_PROJECT_NAME env var (project dir name if env var is not set) and name value from the compose file. For older docker-compose command the name is appended to COMPOSE_PROJECT_NAME with an underscore, but the newer docker compose command appends the two with a hyphen/dash -

Consider the compose file:

services:
  web:
    build: ./webapp

Assuming this compose file is present in the directory my_proj, the build command will generate different image tags.

docker-compose build web will generate docker.io/library/my_proj_web

docker compose build web will generate docker.io/library/my_proj-web

Pankaj
  • 888
  • 10
  • 11