【问题标题】:Access container_name in Dockerfile (from docker-compose)访问 Dockerfile 中的 container_name(来自 docker-compose)
【发布时间】:2020-12-04 06:16:03
【问题描述】:

我已经设置了一个正在创建多个图像的 docker-compose 项目:

cache_server:
    image: current_timezone/full-supervisord-cache-server:1.00
    container_name: renamed-varnish-cache
    networks:
      - network_frontend
    build:
      context: "./all-services/"
      dockerfile: "./cache-server/Dockerfile.cacheserver.varnish"
      args:
        - DOCKER_CONTAINER_USERNAME=username
    ports:
      - "6081:6081"
      - "6082:6082"

当我使用docker-compose up -f file1.yml file2.override.yml 时,我将获得容器:在上述情况下,它将被命名为:renamed-varnish-cache

在相应的 Dockerfile (./nginx-proxy/Dockerfile.proxy.nginx) 中,我希望能够使用上面显示的docker-compose.yml 中定义的container_name 属性。

创建容器后,我想更新 Dockerfile 内的 Varnish 配置:RUN sed -i "s|webserver_container_name|renamed-varnish-cache|g" /etc/varnish/default.vcl"

例如:

    backend webserver_container_name{
        .host = "webserver_container_name";
        .port = "8080";
    }

致:我预计我必须将后端的 - 替换为 _

    backend renamed_varnish_cache{
        .host = "renamed-varnish-cache";
        .port = "8080";
    }

有没有办法接收 docker-compose 命名项目作为 Dockerfile 中的变量?

【问题讨论】:

  • 您可以从同一个镜像启动多个容器,因此您无法知道镜像构建时最终的容器名称可能是什么(在 Dockerfile 中)。
  • 我试图在我的问题docker-compose up -f file1.yml file2.override.yml 中进行推断,这意味着我在 docker-compose 文件中指定了 container_name,换句话说,如果我有多个容器,我会使用另一个覆盖文件。我本来希望动态填充这些内容。也许我错过了使用预定义名称构建图像的概念,如果您覆盖 docker-compose 文件,它们仍将使用 old image 而不是 create a new image ;这就是你想告诉我的吗?
  • "我一运行docker-compose up -d,它就会使用旧图像并且不会重新创建新图像?"不知道你是不是这个意思?如果是这样的话,docker-compose 的用处就不是那么大了。

标签: docker docker-compose dockerfile


【解决方案1】:

在核心 Docker 中,有两个独立的概念。 image 是一些软件的构建版本,它与其依赖项打包在一起; 容器 是图像的运行实例。有单独的 docker builddocker run 命令来构建镜像和启动容器,您可以从单个镜像启动多个容器。

Docker Compose 封装了这些概念。特别是,build: 块对应于镜像构建步骤,这就是调用 Dockerfile 的内容。 其他 Compose 选项在 Dockerfile 中均不可用或可见。您无法访问 container_name:environment: 变量或 volumes:,因为在构建生命周期中此时不存在这些选项;您也无法从 Dockerfile 中联系其他 Compose 服务。

如果多个容器具有基本相同的代码库但需要不同的顶级命令,则它们运行同一个映像是很常见的。一个例子是需要 Celery 后台工作人员的 Python Django 应用程序;您将拥有相同的项目结构,但 Celery 工作人员的命令不同。

version: '3.8'
services:
  web:
    build: .
    image: my/django-app
  worker:
    image: my/django-app
    command: celery worker ...

现在使用此堆栈,您可以docker-compose build 构建一个映像,然后运行docker-compose up 从该映像启动两个容器。 (在构建过程中,您无法知道容器名称是什么,并且会有两个容器名称,因此您不能只在 Dockerfile 中使用一个。)

在设计级别,这意味着您通常不能在映像本身中包含配置类型设置(其他容器的主机名、主机共享文件系统的用户 ID)。如果您的应用程序允许您将这些内容指定为环境变量,那么这是最简单的选择。您可以使用绑定挂载 (volumes:) 来注入整个配置文件。如果这些都不适合你,你可以use an entrypoint script to rewrite the config file

【讨论】:

  • 感谢您的详细解答。我已经忙于使用入口点而不是RUN,因为您之前的评论暗示我做错了。
  • 作为一个附加问题,我想与此类似 - 请您在那里协助我。正如您从那个问题中看到的那样,我确实使用了您解释的这个概念(基本图像到多个子图像),但不知何故,我真的误解了 docker-compose 可以为我做什么。您能否也看看question here,因为那里没有人回答。
猜你喜欢
  • 2020-11-23
  • 1970-01-01
  • 2021-08-21
  • 1970-01-01
  • 1970-01-01
  • 2019-07-30
  • 2019-11-21
  • 2023-01-22
  • 2020-07-11
相关资源
最近更新 更多