使用相同的组合文件(图像名称和容器名称不同)启动两个服务会导致其他服务停止

Starting two services with the same compose file (different in image's name and container's name) cause others stop

在我的项目中,我有一个docker-compose.yml如下:

version: '3.9'

services:
  my-service:
    build:
      dockerfile: ./Dockerfile
      context: ./
    image: "my-service:${IMAGE_VERSION}"
    container_name: my-service-$IMAGE_VERSION
    restart: always
  ...

然后,我有两个环境文件,

...
IMAGE_VERSION=dev
...
...
IMAGE_VERSION=latest
...

我没有 .env 文件。

每次想开发,我运行docker-compose --env-file .env.dev up --build。当我想部署时,我 运行 docker-compose --env-file .env.prod up --build.

虽然Docker镜像的名称和容器的名称在每个进程中都不同,但我不能运行同时提供这两种服务(在同一台主机上)。例如,当我使用 .env.prod env 部署时,它总是重新创建 dev 容器,使 my-service-dev 停止。 (日志:FatalError: 'Termination signal' is detected by the operating system.

Successfully built 119ce748c6f5                                                                                                                                                                                                            
Successfully tagged my-service:latest                                                                                                                                                                                                   
Recreating my-service-dev ... done ==> THIS LINE!                                                                                                                                                                                                 
Attaching to my-service-latest  

是什么Docker机制导致了这样的后果?我怎样才能避免它?还是我必须创建两个不同的撰写文件?

这是正常现象,因为项目名称默认由您的文件夹名称决定。在这两种情况下都是一样的,就像内部 service-name 一样。如果您通过 docker inspect 检查它,您将得到:

 "Config": {
            "Labels": {
                "com.docker.compose.project": "folder_name",
                "com.docker.compose.service": "service_name",
            }
        }

如果您使用的是 .env 文件,只需添加

.env.dev:
COMPOSE_PROJECT_NAME=your_app_dev
.env.prod:
COMPOSE_PROJECT_NAME=your_app_prod

并且您可以启动两者,因为您更改了项目名称。

如果必须使用同一网络,请添加:

services:
  your_service:
    networks:
      - test_network
networks:
  test_network:
    name: test_network

name 很重要,因为用其他项目名称组成前缀。 两个容器都将其服务名称作为网络别名,并且是相同的。因此,如果您想 DNS-resolve 其中之一,请确保不要使用 service_name。也许使用相同的别名还有其他问题,但不知道..到目前为止启动没有问题.. 如果他们不需要交互,只需继续 compose 做它的默认操作,dev/prod 将加入两个独立的网络。