[Fixed] Command ‘docker-compose’ not found (Docker Compose V2 Migration): Step-by-Step Troubleshooting Guide

Overview & Root Cause Summary: The error bash: docker-compose: command not found (or zsh: command not found: docker-compose) occurs on Linux and macOS terminal environments when executing legacy Compose commands. Following Docker’s official retirement of Compose V1 (the legacy Python standalone binary), Docker transitioned Compose to a native Go plugin integrated directly into the Docker CLI as docker compose (with a space). Existing shell scripts, CI/CD pipelines, and developer environments invoking the hyphenated docker-compose binary fail unless the modern plugin or a compatibility shim is installed.

Understanding the Root Causes

  • Official Deprecation of Compose V1: Docker officially retired Compose V1 in July 2023, discontinuing distribution of the standalone Python-based docker-compose binary.
  • Transition to Docker CLI Plugin (V2): Modern Docker installations provide Compose as a modular CLI plugin invoked via docker compose, rendering the hyphenated binary obsolete out-of-the-box.
  • Missing docker-compose-plugin Package: Minimal Linux OS images or standard package manager installs (e.g., docker.io or docker-ce) installed without the companion plugin package.
  • Legacy Automation Scripts: Existing Makefile, CI/CD shell scripts (GitHub Actions, GitLab CI, Jenkins), or documentation referencing legacy Compose syntax.

Step 1: Quick Fix (Adopt Docker Compose V2 Syntax & Shell Alias)

Substitute the hyphen with a space to invoke the modern V2 Compose plugin directly, and establish an alias for backward compatibility in your interactive shell.

# 1. Test invoking Compose via the modern Docker CLI syntax:
docker compose version

# 2. Add an alias to your shell profile (~/.bashrc or ~/.zshrc) for seamless backward compatibility:
echo "alias docker-compose='docker compose'" >> ~/.bashrc
# For Zsh users:
echo "alias docker-compose='docker compose'" >> ~/.zshrc

# 3. Reload your active shell configuration:
source ~/.bashrc  # or source ~/.zshrc

Step 2: Install the Official docker-compose-plugin via Package Manager

If docker compose itself reports that Compose is unrecognized, install the official plugin from Docker’s repositories.

# On Ubuntu / Debian:
sudo apt-get update
sudo apt-get install -y docker-compose-plugin

# On RHEL / CentOS / Rocky Linux / Fedora:
sudo dnf install -y docker-compose-plugin

# On Alpine Linux:
apk add --no-cache docker-cli-compose

Step 3: Create a Global Shim or Install Standalone Binary for CI/CD

For headless CI/CD runners, Dockerfiles, or automation scripts where shell aliases do not apply, install a global wrapper shim or standalone binary.

# Approach A: Create a lightweight global wrapper shim in /usr/local/bin:
cat << 'EOF' | sudo tee /usr/local/bin/docker-compose
#!/bin/sh
exec docker compose "$@"
EOF
sudo chmod +x /usr/local/bin/docker-compose

# Approach B: Download the standalone Docker Compose V2 binary directly:
sudo curl -SL "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" \
    -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Verification & Testing Steps

Confirm that both modern and legacy Compose commands resolve correctly and interact with your Docker daemon.

# 1. Verify modern Compose plugin installation:
docker compose version

# 2. Verify legacy command compatibility through shim or alias:
docker-compose --version

# 3. Test spinning up a container stack:
docker compose up -d
docker compose ps
docker compose down

Summary Comparison Table

Resolution Strategy Applied Scope CI/CD Compatible Recommended Scenario
Native docker compose Direct CLI Command Yes (Recommended standard) All new development and updated scripts
Shell Alias (alias docker-compose) Interactive Terminal Shell No (Aliases skipped in subshells) Local developer workstations for habit retention
APT/DNF docker-compose-plugin System Package Level Yes Fresh Linux server & VM provisioning
Wrapper Shim in /usr/local/bin Global System Path Yes (Executes in all subshells) Legacy CI/CD pipelines & third-party tooling

Leave a Reply

Discover more from Victor's room

Subscribe now to keep reading and get access to the full archive.

Continue reading