【问题标题】:How to prevent docker-compose building the same image multiple times?如何防止 docker-compose 多次构建相同的图像?
【发布时间】:2016-11-30 22:15:13
【问题描述】:

我的docker-compose.yml 指定了多个图像。其中两个镜像是使用相同的本地Dockerfile 构建的。它们共享相同的图像名称,但每个都有不同的命令。

在开发过程中,我经常使用docker-compose up --build 来重建镜像。问题是 docker 两次构建相同的 myimage - 花费的时间比必要的要长。

有没有办法表示镜像只需要构建一次?

version: '2'
services:

  abc:
    image: myimage
    command: abc
    build:
      context: .
      dockerfile: Dockerfile

  xyz:
    image: myimage
    command: xyz
    build:
      context: .
      dockerfile: Dockerfile

【问题讨论】:

  • 除非您将 CMD 指令放在 Dockerfile 的顶部,否则构建缓存应该意味着第二次运行只需几秒钟。第二次运行需要多少时间?
  • 两种构建都需要大约 10 秒,具体取决于机器
  • 也许在 compose 之外构建? docker build -t myimage . && docker-compose up

标签: docker docker-compose


【解决方案1】:

每个the docker-compose file documentation 用于构建,指定build:image: 用于第一个服务,然后仅image: 用于后续服务。

这是您示例的修改版本,它只构建一次图像(用于 abc 服务)并将该图像重用于 xyz 服务。

version: '2'
services:

  abc:
    image: myimage
    command: abc
    build:
      context: .
      dockerfile: Dockerfile

  xyz:
    image: myimage
    command: xyz

【讨论】:

  • 这是(仍然?)最好的方法吗?如果您定期添加和删除此图像的实例,它非常难看,而且绝对容易出错,必须始终确保其中 1 个实例包含构建指令。
  • 在重新阅读答案中链接的文档后,这似乎仍然是最小化docker-compose up --build 时间的最佳方法。
  • 别忘了在 xyz 服务中添加depends_on: [abc]
  • 使用这种方法,docker-compose pull 现在尝试从 Docker Hub 中提取“myimage”……但它显然不存在。否则,这种方法可以节省我一分钟或更多的构建时间。
  • 好的,但在这种情况下,如果不先运行 docker-compose build abc,我将无法为 xyz 构建容器。我是,如果我只运行docker-compose up xyz,图像myimage 将无法构建,它会出错。假设我不想为服务xyz 添加depends_on: abc,因为我不在乎其他服务是否启动。我只想要它的形象
【解决方案2】:

您可以伪造仅构建服务来构建映像,然后将依赖项用于实际工作人员。这样做的好处是,如果您想启动其他服务,您不会自动启动其中一项服务。

您需要为构建服务添加一个映像名称以指定build:image:,并确保它终止并且永远不会自动重新启动。 然后image:depends_on: first_service 为您服务。

像这样:

version: '2'
services:
  _myimage_build:
    image: myimage
    command: ['echo', 'build completed']  # any linux command which directly terminates.
    build:
      context: .
      dockerfile: Dockerfile

  first_service:
    image: myimage
    depends_on:
    - _myimage_build
    command: abc
    
  second_service:
    image: myimage
    depends_on:
    - _myimage_build
    command: xyz

感谢@amath 的回答。

【讨论】:

    【解决方案3】:

    为了让@amath 好的答案更清楚一点

    第一个服务需要添加图片名称build:image:,后续服务需要添加image:depends_on: first_service

    像这样:

    version: '2'
    services:
    
      first_service:
        image: myimage
        command: abc
        build:
          context: .
          dockerfile: Dockerfile
    
      second_service:
        image: myimage
        command: xyz
        depends_on:
        - first_service
    

    感谢@DrSensor 的评论

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-16
      相关资源
      最近更新 更多