Overview
Docker Compose derives a project name to namespace containers, networks, and volumes. Collisions happen when:
- Two services define the same container_name.
- Two Compose projects share the same project name (default: current directory name), leading to conflicting container, network, or volume names.
This guide shows quick fixes and durable patterns to avoid “services have duplicate names” and project name collisions.
Quickstart
- Do not set container_name unless you absolutely need a fixed name.
- Give each project a unique name with -p or COMPOSE_PROJECT_NAME (or top-level name: in the file).
- Clean up old resources with docker compose down before relaunching.
Commands:
# Prefer: unique project names
docker compose -p myproj up -d
# If you ran a conflicting project earlier
docker compose -p myproj down --volumes --remove-orphans
# List running projects
docker compose ls
Minimal working example (and fix)
Problem: duplicate container_name in one compose file.
# docker-compose.yml (broken)
services:
web:
image: nginx:alpine
container_name: app
api:
image: nginx:alpine
container_name: app # duplicates the name used by web
Fix: remove container_name so Compose namespaces by project, or make names unique.
# docker-compose.yml (fixed: let Compose name containers)
name: demoapp # optional; or pass -p demoapp
services:
web:
image: nginx:alpine
api:
image: nginx:alpine
Bring it up safely:
docker compose up -d # or: docker compose -p demoapp up -d
Common symptoms and what they mean
- The container name "/web" is already in use: you set container_name: web in more than one service or project.
- network app_default is ambiguous/already exists: two projects share the same project name (e.g., both directories named app).
- services have duplicate names: two definitions collide across merged compose files or a copy/paste conflict.
Step-by-step: diagnose and resolve
- Identify the collision type
- List running projects and containers:
docker compose ls
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
- Convert your config to see effective names and merges:
docker compose convert
- Eliminate container_name collisions
- Remove container_name unless you need a stable name for legacy discovery.
- If you must use container_name, make it project-specific via environment:
services:
web:
image: nginx:alpine
container_name: "${COMPOSE_PROJECT_NAME:-myproj}_web"
- Set a unique project name Choose one of:
- CLI: docker compose -p myproj up -d
- Env var (shell): export COMPOSE_PROJECT_NAME=myproj
- Compose file: top-level name: myproj
Example:
name: checkout-svc
services:
db:
image: postgres:16
api:
build: ./api
Or via CLI:
docker compose -p checkout-svc up -d
- Clean up previous resources
- Shut down the conflicting project and remove its network/volumes if needed:
# If you know the old project name
docker compose -p app down --volumes --remove-orphans
# Remove a stray network/volume if left behind
docker network rm app_default || true
docker volume ls | awk '/app/{print $2}' | xargs -r docker volume rm
- Merging multiple compose files without collisions When using -f base.yml -f override.yml, Compose merges services by name. Keep service keys unique or intentionally merged.
- Good: same service key intentionally extended across files.
- Avoid: defining two different services that accidentally share the same key.
Check the result with:
docker compose -f base.yml -f override.yml convert --services
- Avoiding network/volume name collisions Let Compose auto-name networks/volumes, or add project-specific names:
name: shop
volumes:
dbdata:
name: "${COMPOSE_PROJECT_NAME:-shop}_dbdata"
networks:
backend:
name: "${COMPOSE_PROJECT_NAME:-shop}_backend"
services:
db:
image: postgres:16
volumes:
- dbdata:/var/lib/postgresql/data
networks: [backend]
Pitfalls to avoid
- Using container_name breaks scaling (docker compose up --scale web=3) and increases collision risk.
- Two different repos with the same folder name create the same default project name. Use -p or name: to distinguish.
- Hard-coding network/volume names without a project prefix causes cross-project conflicts.
- Orphan resources from older runs can keep names occupied; use --remove-orphans and docker compose ls to audit.
- Switching between docker-compose (v1) and docker compose (v2) can change behavior; prefer the v2 plugin and commands shown here.
Performance notes
- Avoid container_name to keep Compose’s parallel deploys and scaling fast.
- Reusing a project name speeds incremental updates by reusing networks/volumes; change it only when you need isolation.
- Many unique project names create many networks/volumes; periodically prune when safe:
docker network prune -f
docker volume prune -f
- Prefer named volumes over bind mounts for database data on macOS/Windows for better I/O performance; they also namespace cleanly per project.
Tiny FAQ
Can I run the same compose app twice on one host? Yes. Run each with a different project name: docker compose -p app1 up -d and docker compose -p app2 up -d.
How do I find my project name? docker compose ls shows running projects. If not set explicitly, it defaults to the directory name or the name: field.
What does “network <x> already exists” mean? Another project created a network with that name. Use a unique project name or remove the old network.
Do I need container_name for inter-service DNS? No. Use the service name on the project network (e.g., http://api:8080). Compose’s internal DNS resolves it.
How do I fix duplicate services across files? Merge intentionally (same key extends) or rename one of the services so each logical service has a unique key within the project.