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.
Option 1: from Docker’s apt repository (recommended)
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
-
Commands: replace
docker-composewithdocker compose. All the subcommands you know (up -d,down,logs -f,ps,pull) work the same. -
Container names change. v1 named containers
project_service_1(underscores); v2 usesproject-service-1(hyphens). When you first rundocker compose up -din 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.
- Bring the stack down with v1 first (
-
version:key. The top-levelversion: "3.8"line is obsolete; v2 ignores it and prints a warning. Delete it. -
File name. v2 prefers
compose.yamlbut still readsdocker-compose.yml. -
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.