【问题标题】:Docker-compose file builds same images twiceDocker-compose 文件两次构建相同的图像
【发布时间】:2021-03-08 09:33:38
【问题描述】:

我正在尝试为我的应用构建图像。但是,当我运行“docker-compose up”命令时,它会构建一些容器两次。我想不出它的原因。我认为标签会导致这种情况,但我无法弄清楚“最新”标签的来源。

这是我的 docker-compose.yml:

version: '3.2'

services:
  elasticsearch:
    build:
      context: elasticsearch/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./elasticsearch/config/elasticsearch.yml
        target: /usr/share/elasticsearch/config/elasticsearch.yml
        read_only: true
      - type: volume
        source: elasticsearch
        target: /usr/share/elasticsearch/data
    ports:
      - "9200:9200"
      - "9300:9300"
    environment:
      ES_JAVA_OPTS: "-Xmx256m -Xms256m"
      ELASTIC_PASSWORD: changeme
      # Use single node discovery in order to disable production mode and avoid bootstrap checks.
      # see: https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
      discovery.type: single-node
    networks:
      - elk

  logstash:
    build:
      context: logstash/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./logstash/config/logstash.yml
        target: /usr/share/logstash/config/logstash.yml
        read_only: true
      - type: bind
        source: ./logstash/pipeline
        target: /usr/share/logstash/pipeline
        read_only: true
    ports:
      - "5044:5044"
      - "5000:5000/tcp"
      - "5000:5000/udp"
      - "9600:9600"
    environment:
      LS_JAVA_OPTS: "-Xmx256m -Xms256m"
    networks:
      - elk
    depends_on:
      - elasticsearch

  kibana:
    build:
      context: kibana/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./kibana/config/kibana.yml
        target: /usr/share/kibana/config/kibana.yml
        read_only: true
    ports:
      - "5601:5601"
    networks:
      - elk
    depends_on:
      - elasticsearch

  zookeeper:
    image: 'bitnami/zookeeper:latest'
    container_name: zookeeper
    ports:
      - "2181:2181"
    networks:
      - elk
    environment:
      - ALLOW_ANONYMOUS_LOGIN=yes

  kafka:
    image: 'bitnami/kafka:latest'
    depends_on:
      - zookeeper
    ports:
      - "9092:9092"
      - "9093:9093"
    networks:
      - elk
    environment:
      KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper:2181
      ALLOW_PLAINTEXT_LISTENER: 'yes'
      KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CLIENT:PLAINTEXT,EXTERNAL:PLAINTEXT
      KAFKA_CFG_LISTENERS: CLIENT://:9092,EXTERNAL://:9093
      KAFKA_CFG_ADVERTISED_LISTENERS: CLIENT://kafka:9092,EXTERNAL://localhost:9093
      KAFKA_INTER_BROKER_LISTENER_NAME: CLIENT
    links:
      - logstash

  app:
    container_name: "ml-pipeline"
    build: .
    ports:
    - "7000:7000"
    - "5001:5001"
    depends_on:
      - kafka
      - elasticsearch
      - logstash
    networks:
      - elk
    links:
      - kafka

networks:
  elk:
    driver: bridge

volumes:
  elasticsearch:

这个输出是:

如您所见,有重复的图像。我该如何解决?

【问题讨论】:

  • 复制的图片在哪里?你所有的图片都是独一无二的
  • @LinPy docker.elastic.co/kibana/kibana 和 twitter-stream-dl-docker_kibana 是 sama 图像,即使它们的大小相同。它们只是在增加尺寸

标签: docker docker-compose


【解决方案1】:

实际上没有任何迹象表明docker-compose 构建了两次图像。您的屏幕截图显示图像具有多个标签名称。但如果没有进一步的上下文,很难说这是如何发生的以及docker-compose 是如何参与其中的。

一个可能的原因:

  • 来自docker.elastic.co 的预构建图像由docker pull docker.elastic.co/... 或另一个docker run 命令下载
  • docker-compose up 正在寻找名为 twitter-stream-dl-docker_* 的图像,由于找不到它们触发了 docker-compose build
  • docker-compose build 构建图像 - 但使用 docker 构建缓存它可以重用现有 docker.elastic.co/... 图像的所有层,这些图像必须是从同一来源构建的
  • 新构建的图像生成相同的最终图像,然后使用docker-compose 预期的名称进行标记,即twitter-stream-dl-docker_*

如果你想强制一个新的本地构建:

  • 在不使用缓存的情况下构建:docker-compose build --no-cache
  • 删除下载的图片:docker rmi docker.elastic.co/...

【讨论】:

  • 感谢您温柔而详细的回答。我通过编写自己的 docker-compose.yml 来影响这个存储库。你能看看这个吗? github.com/deviantony/docker-elk你能告诉我需要做些什么来解决这个问题吗?
  • 我也无法删除下载的图片docker.elastic.co/...因为它引用了其他图片。
  • 很大程度上取决于您要在此处修复的内容,因为实际上没有任何损坏?要删除/取消标记下载的图像,首先删除所有使用它们的容器。要构建您自己的图像,请尝试使用--no-cache。但是现在,构建会产生完全相同的图像,因为它们是使用完全相同的命令和文件构建的。所以结果是预期的/正确的。
【解决方案2】:

所有 3 个 ELK 容器都有一个带有 Dockerfile 的构建上下文,默认情况下只包含一个 FROM 行。在 Dockerfiles 中你可以添加额外的插件。

你的 docker-compose.yml 的一部分:

    build:
      context: logstash/
      args:
        ELK_VERSION: $ELK_VERSION

logstash/Dockerfile:

ARG ELK_VERSION

# https://github.com/elastic/logstash-docker
FROM docker.elastic.co/logstash/logstash:${ELK_VERSION}

# Add your logstash plugins setup here
# Example: RUN logstash-plugin install logstash-filter-json

docker-compose 拉取图像docker.elastic.co/logstash/logstash:${ELK_VERSION} 并构建它自己的版本版本twitter-stream-dl-docker_XXX。由于构建不做任何事情,它只是用新标签标记旧图像,因此它们具有相同的图像 ID。

如果您想知道您的文件夹名称是 twitter-stream-dl-docker,那么图像具有该标签(或者您使用了 docker-compose -p twitter-stream-dl-docker)。

我希望这可以解决问题,但请随时提出任何模棱两可的问题。

【讨论】:

  • 当我使用这个docker-compose -p twitter-stream-dl-docker 时,我会只看到 1 个 Elasticsearch、Logstash 和 Kibana 图像吗?
  • 这其实是正确答案! Dockerfiles 中的FROM 命令将下载docker.elastic.co/... 图像作为基础图像。但是由于Dockerfiles 中没有其他命令,因此生成的最终图像与下载的基本图像相同。如果您不向图像添加任何其他内容,请在 docker-compose.yml 中使用 image 而不是 build
  • 使用COMPOSE_PROJECT_NAME--profile-name / -p flag 您可以设置项目名称,这将影响图像名称,但无论如何都会构建它们。
  • 我使用了docker-compose -p twitter-stream-dl-docker up 命令。它没有用。稍后,我将尝试在docker-compose.yml 文件中使用image 而不是build
  • -p 标志只负责项目名称,这意味着图像、卷、容器、网络的前缀。默认情况下,项目的名称是文件夹的名称,但您可以使用 ENV 变量或-p 标志覆盖它。正如 acran 指出的那样,您想直接使用 image 而无需 docker-compose.yml 中的构建上下文。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-13
  • 1970-01-01
  • 1970-01-01
  • 2020-05-07
  • 2020-12-29
相关资源
最近更新 更多