Docker 不是创建新容器,而是重新创建运行一个 [英] Docker is not creating new container but recreates running one

查看:14
本文介绍了Docker 不是创建新容器,而是重新创建运行一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有以下问题.我正在使用 docker-compose 来构建和启动两个容器.我使用不同的 docker-compose.yml 文件(图像和容器名称不同)多次执行此操作,并且它运行良好并且三个容器并行运行.唯一的区别是,一个容器公开特定端口,而另一个容器运行连接到特定端点的应用程序.所以总的来说,容器并没有什么不同,但它们是.

但现在我创建了三个额外的组合配置,并尝试像我已经对其他三个配置一样并行运行它们.现在的问题是,使用 docker-compose,正在构建和启动一个容器.但是第二个将停止创建的容器并重新创建它.我尝试执行 docker-compose build --no-cache 和之后的 docker-compose up -d,但我仍然遇到了同样的问题.图像虽然不同(ID).在此之前,我仅使用 docker-compose up -d --build 为第一个和第二个(新)容器尝试了它,它将像提到的那样重新创建.但是查看图像,他们会得到相同的 ID(但名称不同).

所以我认为docker在缓存方面有问题.这就是为什么我最终删除了所有容器和图像并从头开始使用选项 --no-cache 如上所述.不过没用.

这里有两个有效的 docker-compose.yml:

版本:'2'服务:红宝石:安全选择:- seccomp:无限制建造:语境: .dockerfile: Dockerfile_ruby参数:- http_proxy=http://someIP:3128- https_proxy=http://someIP:3128图片:ruby_foo_ge01容器名称:ruby_container_ge01卷:-/home/foo/log/GE01/:/usr/src/app/log/ssl:安全选择:- seccomp:无限制建造:语境: .dockerfile: Dockerfile_ssl参数:- http_proxy=http://someIP:3128- https_proxy=http://someIP:3128图片:ssl_ge01容器名称:ssl_container_ge01卷:-/home/foo/log/GE01/nginx/:/var/log/nginx/端口:- 3003:443"链接:- 红宝石

另一个:

版本:'2'服务:红宝石:安全选择:- seccomp:无限制建造:语境: .dockerfile: Dockerfile_ruby参数:- http_proxy=http://someIP:3128- https_proxy=http://someIP:3128图片:ruby_foo容器名称:ruby_container卷:-/home/foo/log/:/usr/src/app/log/ssl:安全选择:- seccomp:无限制建造:语境: .dockerfile: Dockerfile_ssl参数:- http_proxy=http://someIP:3128- https_proxy=http://someIP:3128图片:ssl_gt01容器名称:ssl_container卷:-/home/foo/log/nginx/:/var/log/nginx/端口:- 3001:443"链接:- 红宝石

使用 docker-compose up -d --build 运行这两个和另一个非常相似是没有问题的.

这里有两个失败的容器 .yml 文件:

版本:'2'服务:红宝石:安全选择:- seccomp:无限制建造:语境: .dockerfile: Dockerfile_ruby参数:- http_proxy=http://someIP:3128- https_proxy=http://someIP:3128图片:ruby_foo_websock_gt01容器名称:ruby_containerWSgt01卷:-/home/foo/websockGT01/log/:/usr/src/app/log/ssl:安全选择:- seccomp:无限制建造:语境: .dockerfile: Dockerfile_ssl参数:- http_proxy=http://someIP:3128- https_proxy=http://someIP:3128图片:ssl_websock_gt01容器名称:ssl_containerWSgt01卷:-/home/foo/websockGT01/log/nginx/:/var/log/nginx/端口:- 3010:443"链接:- 红宝石

第二个:

版本:'2'服务:红宝石:安全选择:- seccomp:无限制建造:语境: .dockerfile: Dockerfile_ruby参数:- http_proxy=http://someIP:3128- https_proxy=http://someIP:3128图片:ruby_foo_websock_ge01容器名称:ruby_containerWSge01卷:-/home/foo/websockGE01/log/:/usr/src/app/log/ssl:安全选择:- seccomp:无限制建造:语境: .dockerfile: Dockerfile_ssl参数:- http_proxy=http://someIP:3128- https_proxy=http://someIP:3128图片:ssl_websock_ge01容器名称:ssl_containerWSge01卷:-/home/foo/websockGE01/log/nginx/:/var/log/nginx/端口:- 3030:443"链接:- 红宝石

如您所见,工作的 .yml 文件和失败的 .yml 文件没有太大区别.(或者我错过了什么?)图像和容器名称随着暴露的端口和卷路径而变化.所有文件都有自己的工作目录,应用程序代码也保存在每个实例中.所有使用的 Dockerfiles 在每个工作目录中都是相同的.

TL;DR:为什么我的 docker-compose 没有启动一个新容器,而是停止一个正在运行的容器并重新创建那个容器?是否有最大数量的运行容器?我在 .yml 文件中做错了什么吗?正如开头提到的 --no-cache 没有帮助.

对那堵文字墙表示亲切的问候和抱歉

解决方案

简短回答

当您运行 docker-compose up 时,有时您似乎在使用相同的项目名称;由于您在 docker-compose.yml 文件之间使用相同的服务名称(即 rubyssl),Docker Compose 将不同的配置视为修改相同的服务,而不是将它们完全视为独立的服务.

我的猜测是一些docker-compose.yml文件的父目录是一样的,所以如果你想同时运行这些容器,你有几个选择:

  • 更改父目录的名称,使它们都不同
  • 在每次调用 docker-compose up 时指定不同的项目名称,例如docker-compose -p project1 up -d, docker-compose -p project2 up -d
  • 更改服务名称,使它们在不同的 docker-compose.yml 文件中不完全相同

更长的答案

通过快速测试,Docker Compose 似乎使用项目名称和服务名称来标识特定服务.在运行 Docker Compose 命令时,可以使用 -p 标志设置项目名称,否则它使用 COMPOSE_PROJECT_NAME 环境变量的值(如果设置),如果两者都没有指定它将默认为 docker-compose.yml 文件的父目录的名称(请参阅 https://docs.docker.com/compose/reference/overview).

因此,给定目录结构,例如:

<预><代码>.├── a│ └── z│ └── docker-compose.yml├── b│ └── z│ └── docker-compose.yml└── c└── y└── docker-compose.yml

a/z 目录运行 docker-compose up -d(或使用 docker-compose -fa/z/docker-compose.yml up-d) 将在项目 z 中启动 rubyssl 服务,使用 docker 中指定的容器名称命名-compose.yml.

如果您随后从b/z 目录运行docker-compose up -d,Docker Compose 将看到您尝试再次启动ruby<项目 z 中的/code> 和 ssl 服务,但这次有一些不同,例如名称和端口.它会将此视为您修改了原始 docker-compose.yml,并使用新配置重新启动容器.如果您现在从 c/y 目录运行 docker-compose up -d 那么您将获得两个与前两个并行运行的新容器,rubyssl 服务在项目 y 中运行.

因此,您需要通过更改服务名称或每次设置不同的项目来确保项目和服务名称的组合在您要运行的不同容器集之间有所不同.

so I have the following problem. I'm using docker-compose to build and start two container. I did this multiple times with different docker-compose.yml files (image and container name differ) and it worked fine and three container run parallel. The only difference is, that one container exposes a specific port and the other runs an application that connects to a specific endpoint. So in total the containers are not that different, but they are.

But now I created three additional compose configurations and tried to run them parallel like I'm already doing with the three others. The Problem now is, that with docker-compose, one container is being build and started. But the second one will stop the created container and recreate it. I tried to do docker-compose build --no-cache and after that docker-compose up -d, but I still ended up with the same problem. The images though were different (ID). Before that I tried it just with docker-compose up -d --build for the first and second (new) container and it would be recreated like mentioned. But looking at the images, they would get the same ID (but different name).

So I thought docker has a problem with caching. That's why I ended up deleting all my container and images and started from scratch with the option --no-cache like mentioned above. Didn't work though.

Here are two docker-compose.yml that work:

version: '2'
services:
    ruby:
        security_opt:
            - seccomp:unconfined
        build:
            context: .
            dockerfile: Dockerfile_ruby
            args:
                - http_proxy=http://someIP:3128
                - https_proxy=http://someIP:3128
        image: ruby_foo_ge01
        container_name: ruby_container_ge01
        volumes:
            - /home/foo/log/GE01/:/usr/src/app/log/
    ssl:
        security_opt:
            - seccomp:unconfined
        build:
            context: .
            dockerfile: Dockerfile_ssl
            args:
                - http_proxy=http://someIP:3128
                - https_proxy=http://someIP:3128
        image: ssl_ge01
        container_name: ssl_container_ge01
        volumes:
            - /home/foo/log/GE01/nginx/:/var/log/nginx/
        ports:
            - "3003:443"
        links:
            - ruby

and the other one:

version: '2'
services:
    ruby:
        security_opt:
            - seccomp:unconfined
        build:
            context: .
            dockerfile: Dockerfile_ruby
            args:
                - http_proxy=http://someIP:3128
                - https_proxy=http://someIP:3128
        image: ruby_foo
        container_name: ruby_container
        volumes:
            - /home/foo/log/:/usr/src/app/log/
    ssl:
        security_opt:
            - seccomp:unconfined
        build:
            context: .
            dockerfile: Dockerfile_ssl
            args:
                - http_proxy=http://someIP:3128
                - https_proxy=http://someIP:3128
        image: ssl_gt01
        container_name: ssl_container
        volumes:
            - /home/foo/log/nginx/:/var/log/nginx/
        ports:
            - "3001:443"
        links:
            - ruby

Running this two and one other quite similar with docker-compose up -d --build is no problem.

And here are two .yml files of the container that fail:

version: '2'
services:
    ruby:
        security_opt:
            - seccomp:unconfined
        build:
            context: .
            dockerfile: Dockerfile_ruby
            args:
                - http_proxy=http://someIP:3128
                - https_proxy=http://someIP:3128
        image: ruby_foo_websock_gt01
        container_name: ruby_containerWSgt01
        volumes:
            - /home/foo/websockGT01/log/:/usr/src/app/log/
    ssl:
        security_opt:
            - seccomp:unconfined
        build:
            context: .
            dockerfile: Dockerfile_ssl
            args:
                - http_proxy=http://someIP:3128
                - https_proxy=http://someIP:3128
        image: ssl_websock_gt01
        container_name: ssl_containerWSgt01
        volumes:
            - /home/foo/websockGT01/log/nginx/:/var/log/nginx/
        ports:
            - "3010:443"
        links:
            - ruby

And the second one:

version: '2'
services:
    ruby:
        security_opt:
            - seccomp:unconfined
        build:
            context: .
            dockerfile: Dockerfile_ruby
            args:
                - http_proxy=http://someIP:3128
                - https_proxy=http://someIP:3128
        image: ruby_foo_websock_ge01
        container_name: ruby_containerWSge01
        volumes:
            - /home/foo/websockGE01/log/:/usr/src/app/log/
    ssl:
        security_opt:
            - seccomp:unconfined
        build:
            context: .
            dockerfile: Dockerfile_ssl
            args:
                - http_proxy=http://someIP:3128
                - https_proxy=http://someIP:3128
        image: ssl_websock_ge01
        container_name: ssl_containerWSge01
        volumes:
            - /home/foo/websockGE01/log/nginx/:/var/log/nginx/
        ports:
            - "3030:443"
        links:
            - ruby

As you can see there is no big difference in the working .yml files and the ones that fail. (Or did I miss something?) The image and container names change as does the exposed port and volume path. All of the files have their own working dir where also the application code is saved per instance. All the used Dockerfiles are the same in each working dir.

TL;DR: Why is my docker-compose not starting a new container, but stops a running one and recreates that one? Is there a maximum amount of running container? Have I done something wrong in my .yml file? As mentioned at the beginning --no-cache does not help.

Kind regards and sorry for that wall of text

解决方案

Short(ish) answer

It looks as though you're using the same project name some of the time when you run docker-compose up; since you use the same service names (i.e. ruby and ssl) between docker-compose.yml files, Docker Compose treats the different configurations as modifications of the same service, rather than considering them to be separate services completely.

My guess is that the parent directory of some of the docker-compose.yml files is the same, so if you want to run these containers at the same time you have a few options:

  • Change the names of the parent directories so they're all different
  • Specify a different project name on each invocation of docker-compose up, e.g. docker-compose -p project1 up -d, docker-compose -p project2 up -d
  • Change the service names so they're not all the same across the different docker-compose.yml files

Longer answer

From a quick test it appears that Docker Compose uses the project name and service name to identify a specific service. The project name can be set with the -p flag when running Docker Compose commands, otherwise it uses the value of the COMPOSE_PROJECT_NAME environment variable if set, and if neither of those are specified it'll default to the name of the parent directory of the docker-compose.yml file (see https://docs.docker.com/compose/reference/overview).

So, given a directory structure such as:

.
├── a
│   └── z
│       └── docker-compose.yml
├── b
│   └── z
│       └── docker-compose.yml
└── c
    └── y
        └── docker-compose.yml

Running docker-compose up -d from the a/z directory (or using docker-compose -f a/z/docker-compose.yml up -d) will start ruby and ssl services in project z, named using the container names specified in the docker-compose.yml.

If you then run docker-compose up -d from theb/z directory, Docker Compose will see you trying to again bring up the ruby and ssl services in project z, but this time with some differences, e.g. to names and ports. It will treat this as if you had modified the original docker-compose.yml, and restart the containers with the new configuration. If you were to now run docker-compose up -d from the c/y directory then you would get two new containers running in parallel with the first two, ruby and ssl services running in project y.

So you'll need to ensure that the combination of project and service name differs across the different sets of containers you'd like to run, either by changing the service names or by setting the project differently each time.

这篇关于Docker 不是创建新容器,而是重新创建运行一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆