Operations involving `docker-compose`, particularly `docker-compose up`, may unexpectedly fail following system package updates or pulling new Docker images.
A common manifestation of this issue on Linux systems, such as Ubuntu Server 22.04, is a Python traceback terminating with a KeyError: 'ContainerConfig'
.
This error typically occurs when attempting to recreate or start services defined in a docker-compose.yml
previously functioning file. Another observed symptom might be existing container names appearing altered with random character prefixes when listed using docker ps -a
.
This article examines the underlying cause of this error and outlines several effective strategies for resolution based on common practices.
Understanding the KeyError: ‘ContainerConfig’ Problem
The root cause of the KeyError: 'ContainerConfig'
traceback often lies in using the legacy version 1 (`docker-compose`) command-line tool. This version is deprecated and may exhibit compatibility issues with newer versions of the Docker engine or associated libraries, particularly after system updates.
The error itself indicates that the `docker-compose` script is attempting to access a specific key (`ContainerConfig`) within a container’s image configuration metadata, but this key is not found where expected. This failure often happens during the process of comparing existing container configurations with the desired state defined in the Compose file, specifically when handling volume bindings.
Furthermore, conflicts arising from previously stopped or partially created containers (potentially left behind by earlier failed attempts) can contribute to this error state. The presence of containers with unexpected name prefixes (e.g., #random_string#_#original_name#
) is often a symptom of these underlying conflicts or issues encountered by the older `docker-compose` version.
Docker Compose has transitioned from a standalone Python script (V1) to an integrated Docker CLI plugin (V2). The recommended approach is to use the modern V2 syntax.
Read: How to Fix Docker Host IP Address and Port Mappings from Within a Container
Resolution Strategies
Several approaches can resolve the `KeyError: ‘ContainerConfig’` issue.
Primary Solution: Adopt Docker Compose V2 Syntax
The most direct and recommended solution is to switch from the V1 (`docker-compose`) syntax to the V2 (`docker compose`) syntax. V2 is integrated directly into the Docker CLI and avoids the compatibility issues associated with the deprecated V1 script.
Replace commands like:
sudo docker-compose up -d
With the V2 equivalent:
sudo docker compose up -d
Note that some command flags might differ slightly or are not supported in V2 (e.g., the `-d` shortcut might require the full `–detach` flag in some contexts, although `up -d` is standard).
Installation Considerations:
- On systems like Ubuntu 24.04 LTS, the V2 plugin might not be installed by default, even if Docker is present. It can often be installed using the package manager:
sudo apt-get install docker-compose-v2
- If the official distribution repositories do not yet include V2, obtaining the necessary package (e.g., a
.deb
file) from alternative sources like Debian testing repositories might be a viable, though potentially less stable, option. - Consider removing the legacy V1 package (`docker-compose`) after confirming V2 is installed and functional to prevent accidental usage:
# Example package removal command (adjust for your package manager) sudo apt-get remove docker-compose
Cleanup Existing Container State
Conflicts with existing containers or networks, often created or left by previous V1 attempts, can trigger the error. Cleaning the Docker environment before attempting to start the services again is often effective.
Using `docker compose down`
This command stops and removes containers, networks, and potentially volumes defined in the Compose file. It’s a clean way to reset the state for the specific project.
# Using V2 syntax (recommended)
sudo docker compose down
# Or, if still using V1 temporarily
sudo docker-compose down
After running `down`, attempt the `up` command again.
Caution: Using `docker compose down` (especially with the `–volumes` flag, though not shown here) can remove named volumes associated with your services. If these volumes contain important data (like local development database files), ensure you have backups or understand the implications.
Removing Specific Exited Containers
If a full `down` operation is undesirable, you might identify and remove only the conflicting stopped containers.
1. List all containers, including stopped ones, filtering for those in an “Exited” state:
docker ps -a | grep -i Exited
2. Identify containers related to your Compose project that are stopped and potentially causing conflicts.
3. Remove them using `docker rm #container_id_or_name#`.
4. Retry the `docker compose up -d` command.
Forceful Container Removal
As a more direct cleanup method focused only on containers managed by Compose:
# Using V1 syntax (as presented in discussion)
sudo docker-compose rm -f
Follow this with:
sudo docker-compose up -d # Or preferably: sudo docker compose up -d
Aggressive System-Wide Cleanup (Use with Caution)
In cases where conflicts might stem from broader Docker state issues beyond just the specific Compose project, a system prune can be employed. This is a more drastic measure.
docker system prune --all --volumes
This command removes:
- All stopped containers
- All networks not used by at least one container
- All dangling images
- All build cache
- With
--volumes
: All volumes not used by at least one container
Warning: The --volumes
flag is destructive and will remove data in any unused named volumes. Use this command with extreme caution, especially in production or environments with valuable non-ephemeral data in Docker volumes.
After pruning, attempt the `docker compose up -d` command again.
Integration Adjustments (Ansible Example)
If Docker Compose is managed through automation tools like Ansible, the tool’s modules may need updating to reflect the V1 to V2 transition.
For the `community.docker` collection in Ansible:
- Update tasks using the `community.docker.docker_compose` module to use `community.docker.docker_compose_v2`.
- Review module parameters, as some might change. For example, `pull: true` might need to become `pull: always`.
Alternatively, an Ansible playbook might explicitly orchestrate cleanup before deployment, even when using the older module:
- name: Stopping existing container (using V1 syntax)
shell:
chdir: "#your_project_path#"
cmd: "docker-compose down"
- name: Waiting a moment for containers to stop
ansible.builtin.pause:
seconds: 30
- name: Deploy Docker Compose stack (using V1 syntax)
shell:
chdir: "#your_project_path#"
cmd: "docker-compose build && docker-compose up -d"
While this playbook structure works, migrating the Ansible tasks to use the `docker_compose_v2` module is the preferable long-term approach.
Verifying the Solution
After applying one of the solutions, verify its success by running the intended command to bring up the services:
sudo docker compose up -d
A successful execution will proceed without the `KeyError: ‘ContainerConfig’` traceback. Further confirmation can be obtained by listing the running containers:
docker ps
This command should show the expected containers in a running state with their correct names.
Conclusion
The KeyError: 'ContainerConfig'
error encountered with docker-compose
after updates is typically linked to the deprecated V1 command syntax struggling with modern Docker environments. The primary resolution involves migrating to the current docker compose
V2 syntax. Alternatively, thorough cleanup of potentially conflicting Docker resources (stopped containers, networks) using commands like docker compose down
or, more cautiously, docker system prune
, can also resolve the immediate issue, though adopting V2 is recommended for future compatibility.