KhueApps
Home/DevOps/Fix duplicate service names and project collisions in Docker Compose

Fix duplicate service names and project collisions in Docker Compose

Last updated: October 07, 2025

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

  1. 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
  1. 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"
  1. 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
  1. 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
  1. 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
  1. 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.

Series: Docker

DevOps