Docker Compose 导致“冲突。容器名称已被容器使用”?

Leo*_*ang 2 docker docker-compose

我发现了很多关于此错误的问题,但没有一个是专门关于使用docker compose up. 我运行了docker compose up多次,一切都按预期工作,但偶尔会抛出:

Error response from daemon: Conflict.
The container name "/e752d663bd1a_foo" is already in use by container "e672c49f717291b19dbad4a25a372f96b6af5c7cbe70d50d5f169adf09dcb495".
You have to remove (or rename) that container to be able to reuse that name.
Run Code Online (Sandbox Code Playgroud)

我没有更改 Docker Compose 配置或启动任何新容器等。Docker 应该能够识别该容器是之前由 Docker Compose 启动的,因此它可以重用该容器。

这是我的配置的相关部分:

  foo:
    image: server
    depends_on:
      - broker
      - schema-registry
      - connect
      - redis
    restart: always
    user: root
    environment:
      - SERVER=production
      - NODE_ENV=production
    command:
      - node
      - '--experimental-specifier-resolution=node'
      - '--no-warnings'
      - build/production/foo.js
    volumes:
      - ./env:/usr/src/env
      - ./.env:/usr/src/.env
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 2G
Run Code Online (Sandbox Code Playgroud)

我正在使用的命令:

node ./docker-compose.js | docker compose -f - -p foo --compatibility up -d --remove-orphans
Run Code Online (Sandbox Code Playgroud)

Docker:v25.0.1 Docker Compose:v2.23.3

奇怪的是,尽管配置中有大约 10 个容器,但导致错误的始终是同一个“foo”容器。

编辑赏金:

我删除了“container_name”字段,这个错误出现的频率较低,但我仍然遇到过几次。此外,Docker Compose 有时会在不更改任何配置的情况下重新创建容器,这可能是相关的。

Von*_*onC 7

container_name该错误消息显示容器名称与 Docker Compose 的常用命名模式或您指定的命名模式不匹配。这可能表明外部进程或脚本影响容器管理,从而导致命名冲突。

根据BMitch建议container_name: foo,第一个测试是从 Docker Compose 配置中删除该行。让 Docker Compose 处理命名以避免冲突,尤其是在快速启动/停止周期期间。

services:
  foo:
    image: server
    # Removed container_name: foo
    depends_on:
    ...
Run Code Online (Sandbox Code Playgroud)

使用 Docker 的内部 DNS 服务,而不是依赖固定的容器名称进行容器间通信。Docker Compose 文件中的每个服务都可以通过使用服务名称作为主机名的其他服务来访问。
请参阅“ Compose 中的网络 (V2)

鉴于此,当您container_name从 Docker Compose 配置中删除该指令时,您应该依赖此内部 DNS 服务进行容器间通信。这意味着应用程序中对特定容器名称的任何引用(如果有)都应替换为 Docker Compose 文件中定义的服务名称。

例如,如果 Docker Compose 设置中的其他服务需要连接到该foo服务,它们可以简单地用作foo主机名,而不是硬编码的容器名称。