Docker Compose comes in two generations:

  • Compose v1 — the Python program docker-compose (with a hyphen). End of life since 2023; no more updates, not even security fixes.
  • Compose v2 — written in Go and shipped as a Docker CLI plugin, invoked as docker compose (with a space). It’s what you should use.

The YAML format is the same. This guide shows how to install v2 and move old projects over.

Check what you have

docker compose version     # v2 plugin
docker-compose version     # v1 standalone (or a v2 compatibility shim)

If the first command prints Docker Compose version v2.x.x, you’re done.

If you installed Docker Engine from Docker’s repository (as in installing Docker on Ubuntu or on Debian):

sudo apt-get update
sudo apt-get install -y docker-compose-plugin
docker compose version

On AlmaLinux/Rocky with Docker’s repository: sudo dnf install docker-compose-plugin.

The plugin is then updated along with Docker through normal system updates.

Option 2: manual install (any distribution)

If Docker came from somewhere else, download the binary from the docker/compose GitHub releases into the CLI plugins directory:

COMPOSE_VERSION=v2.30.3   # check the releases page for the current version
sudo mkdir -p /usr/local/lib/docker/cli-plugins
sudo curl -SL "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-linux-$(uname -m)" \
  -o /usr/local/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
docker compose version

For a single user only, use ~/.docker/cli-plugins/ instead. You’ll need to repeat the download to update.

Ubuntu’s own packages

Ubuntu and Debian also package Compose. On recent Ubuntu releases, docker-compose-v2 provides the v2 plugin for Ubuntu’s docker.io. The old docker-compose package may still be v1. Don’t mix Ubuntu’s Docker packages with Docker’s repository packages — pick one source.

Migrating from docker-compose v1

  1. Commands: replace docker-compose with docker compose. All the subcommands you know (up -d, down, logs -f, ps, pull) work the same.

  2. Container names change. v1 named containers project_service_1 (underscores); v2 uses project-service-1 (hyphens). When you first run docker compose up -d in an existing project, v2 creates new containers with new names. Volumes and networks carry over because their names didn’t change, but:

    • Bring the stack down with v1 first (docker-compose down), then up with v2, to avoid two copies running.
    • Update scripts or monitoring that reference container names.
  3. version: key. The top-level version: "3.8" line is obsolete; v2 ignores it and prints a warning. Delete it.

  4. File name. v2 prefers compose.yaml but still reads docker-compose.yml.

  5. Scripts and cron jobs. Search for old invocations:

grep -rn "docker-compose" /etc/cron* /usr/local/bin ~/ 2>/dev/null

Keep the old command working (optional)

If tools still call docker-compose, add a tiny wrapper:

sudo tee /usr/local/bin/docker-compose > /dev/null <<'EOF'
#!/bin/sh
exec docker compose "$@"
EOF
sudo chmod +x /usr/local/bin/docker-compose

Then remove the v1 package (sudo apt remove docker-compose or sudo pip uninstall docker-compose) so it doesn’t shadow the wrapper.

What v2 adds

  • Faster, parallel operations.
  • docker compose up --wait — waits until services are healthy (great for CI).
  • docker compose watch — syncs code changes into containers during development.
  • Profiles (--profile debug) to enable optional services.
  • include: to compose a project from several files.
  • Better integration with BuildKit and Buildx for builds.

Troubleshooting

docker: 'compose' is not a docker command — the plugin isn’t installed or not in a plugin directory. Install docker-compose-plugin, or check the path: ls /usr/libexec/docker/cli-plugins/ /usr/local/lib/docker/cli-plugins/ ~/.docker/cli-plugins/.

unknown shorthand flag: 'd' in -d — you typed docker compose with an old Docker CLI that doesn’t know plugins, or an alias interferes. Check docker version.

version is obsolete warning — delete the version: line from your Compose file.

Two copies of a service after migration — v1 containers (underscore names) are still running. Stop them with docker stop and remove them.

Ready to write Compose files? See the Docker Compose tutorial and environment variables in Compose.

  • Docker
  • Docker Compose
  • Linux