Difference between "docker compose" and "docker-compose" - docker

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:
docker-compose's help:

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.

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

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.

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/#multiple-isolated-environments-on-a-single-host

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

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.

Related

Docker Compose: omitting directory /config/certs.yml, ERROR: no configuration file found

I am trying to use Docker Desktop to run this tutorial to install wazuh in a docker container (single-node deployment). I make a new container in the docker desktop and then try to run the docker compose command in vscode but get the error mentioned in the title. I have tried to change the project directory but it always points to the root directory by /config/certs.yml. my command is
docker-compose --project-directory /com.docker.devenvironments.code/single-node --file /com.docker.devenvironments.code/single-node/generate-indexer-certs.yml run --rm generator
my directory structure is as follows:
where certs.yml is in the config folder, but upon running this command the error always points to the root folder, which is not my project folder. The only folder i want to run this from is the com.docker.devenvironments.code folder, or somehow change where the command finds the certs.yml file. I have also tried cd into different folders and trying to run the command, but get the same error.
Thank you very much in advance for your help!
Looking quickly at the documentation link provided in the question, you can try the following thing:
Move the docker-compose definition from the folder wazuh-docker/single-node/docker-compose.yml to outer directory which is the main definition wazuh-docker in your case it will be com.docker.devenvironments.code I believe into a separate <your_compose.yaml> with the same definition, but change the volume mounts as:
Wazuh App Copyright (C) 2021 Wazuh Inc. (License GPLv2)
version: '3'
services:
generator:
image: wazuh/wazuh-certs-generator:0.0.1
hostname: wazuh-certs-generator
volumes:
- ./single-node/config/wazuh_indexer_ssl_certs/:/certificates/
- ./single-node/config/certs.yml:/config/certs.yml
...
Then, docker-compose -f <your_compose.yaml> up should do. Note: your_defined.yaml is the yaml with the volume mount changes and is created at the root of the project. Also, looking at the image provided in the question, you might want to revisit the documentation and run the command to generate the certificates docker-compose -f generate-indexer-certs.yml run --rm generator from the single-node folder.
You can change the directory of the certs.yml file in the following section of the generate-indexer-certs.yml file:
volumes:
- ./config/certs.yml:/config/certs.yml
You can replace ./config/certs.yml with the path where the certs.yml file is located.
In your case:
volumes:
- /com.docker.devenvironments.code/single-node/config/certs.yml:/config/certs.yml

what is the difference between `docker-compose` and `docker compose` [duplicate]

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:
docker-compose's help:
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.
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
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.
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/#multiple-isolated-environments-on-a-single-host
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
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.

Docker versus Docker-compose with dockerignore

Are docker and docker-compose supposed to differ in their handling of .dockerignore?
I've got a Docker container which builds fine when I build it directly, e.g. via docker build -t mycontainer ./mycontainer, but it fails when I build it via docker-compose up. Relevant portion of the docker-compose.yml is
version: '3'
services:
mycontainer:
build: ./mycontainer
ports:
- "1234:1234"
expose:
- "1234"
By using docker run --rm -it --entrypoint=/bin/bash 240e1a06c8f5, where 240e1a06c8f5 is the last image before the build failure, I found that one of the files, ./mycontainer/mymodel/labels.rdata, wasn't being copied over by docker-compose up, but is copied by docker build. It's also close to a pattern in the .dockerignore, */*.RData.
Is this a difference between case-sensitivity in .dockerignore between docker-compose and docker build? Is it a difference in path handling? Is this a known bug? (or intended?)
Versions on MacOs:
$ docker --version
Docker version 18.09.1, build 4c52b90
$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01
I just tried using a case-insensitive .dockerignore entry on Windows and it did actually ignore the file, so it looks like your */*.RData will actually ignore your ./mycontainer/mymodel/labels.rdata file.
Try changing the extension of the file or changing the ignore entry. I'd change the filename, since that seems like the one-off here.
EDIT: This does sound like a bug. I'd file one on their Github Issues page since I don't see one there already

Set $PROJECT_NAME in docker-compose file

I am using the same docker-compose.yml file for multiple projects. I am really lazy, so I don't want to start them with docker-compose -p $PROJECT_NAME up.
As of Docker version 17.06.0, is it possible to set the variable directly in the docker-compose.yml file?
UPDATE: You can now use the top-level name property in your docker-compose YAML file. This is available from Docker Compose v2.3.3
This is the result of the #745 proposal. An issue which persevered for about 8 years.
Previously:
Right now, we can use the .env file to set the custom project name like this:
COMPOSE_PROJECT_NAME=SOMEPROJECTNAME
It's not flexible, but it's better than nothing. Currently, there is an open issue regarding this as a proposal.
I know this question was asked a long time ago, but I ran into the same problem. There's a suggestion to add the feature https://github.com/docker/compose/issues/745, but they don't want to.
However, I have a Makefile in the root of the directory and then you can add something like in the Makefile:
.PHONY: container-name
container-name:
docker-compose -p $PROJECT_NAME up -d container-name
and then run make container-name
I know it isn't what you asked for, but could maybe make your life a bit easier.
220806 UPDATE: you can now use the top-level name property in your docker-compose YAML file.
This is the result of the #745 proposal.
Update as on Docker Compose version 2.3.3, name can be given in the compose file, but please note the following as per documentation compose-spec at github.com., Compose official documentation
Whenever project name is defined by top-level name or by some custom mechanism, it MUST be exposed for interpolation and environment variable resolution as COMPOSE_PROJECT_NAME.
name: stitch
services:
foo:
image: busybox
environment:
- COMPOSE_PROJECT_NAME
command: echo "I'm running ${COMPOSE_PROJECT_NAME}"
Previously proposed solution :
You can add them as your environment variables which are available through the session in which you are bringing up your containers using the docker compose.
Ie, if you wanted to use $PROJECT_NAME somewhere inside your docker-compose.yaml then if this variable has a value in your session, then it would be picked up.
Inside the yaml you can assign it to anything as you want it. You want as a commandline arg to some script, even that is also possible. ie,
working_dir: /opt
command: /bin/bash -c './script.sh ${PROJECT_NAME}'
volumes:
- /var/run/:/host/var/run/
I'm using
docker version : Docker version 17.09.0-ce, build afdb6d4
docker-compose version : docker-compose version 1.14.0, build c7bdf9e

When using multiple Docker Compose config files in CLI, do they need specifying with all command runs?

When using Docker Compose with multiple configuration files (e.g., to allow multiple environments to share a common configuration file), I can't figure out if all commands in the CLI need to have all config files mentioned.
For example, I have docker.compose.yml and docker.compose.dev.yml, and I launch my dev environment as such:
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
If I want to run a command on a service, I can use:
docker-compose web ls
Or I can use:
docker-compose -f docker-compose.yml -f docker-compose.dev.yml run ls
Both commands work, so I wasn't sure if the configuration files get associated with the containers once they're built.
From what I can tell, if you want the overriding configuration file to be applied when the docker-compose CLI command is run, you need to specify all configuration files.
This may not always be apparent: the examples given in the question (docker-compose web ls and docker-compose -f docker-compose.yml -f docker-compose.dev.yml run ls) may both run without an error (really depends on what command you're running), but all settings in docker-compose.dev.yml will not be applied.
Here's an example of when this can be a problem:
Assume docker-compose.yml has all settings defaulted to a production environment where docker-compose.dev.yml sets these to some safe development setup (this is a horrible environment setup, but maybe other setups will have a similar problem)
Assume web is a Django app that uses django-storages to store static files on a CDN;
When running docker-compose run web python manage.py collectstatic, files would be uploaded to the production address, thus possibly causing unexpected production changes.
With all this in mind, I recommend renaming docker-compose.yml to something like docker-compose.base.yml, thus running docker-compose run web python manage.py collectstatic would error about docker-compose.yml being missing.
Note of alternative setup: an alternative setup for the multiple environments, as described on the referenced Compose documentation, is to use the extends keyword in the docker files. Rackspace developed an sample project, available on Github, that provides a great example of using this feature.

Resources