Compose: docker-compose将文件或目录复制到容器

创建于 2018-01-01  ·  141评论  ·  资料来源: docker/compose

我们错过了使用docker-compose复制文件或目录的可能性。 我觉得这真的很有用。
请在过早关闭的https://github.com/docker/compose/issues/2105中检查许多+1

kinfeature statu0-triage

最有用的评论

仅仅因为在某些情况下最终会引起问题,教条上坚持说它是反模式的用途是什么? 这肯定有很好的用处,因为您可以在现有文件中添加一行,而不必创建额外的文件夹和文件,然后将要添加的文件移动到那里。 微小文件的这种毫无意义的官僚创建是真正的反模式,可防止用户创建简单且易于维护的docker-compose文件。

如果用户想使用Docker做有害的事情,无论您做什么,他们都会找到一种方法。 仅仅因为某天可能滥用某些功能而拒绝添加合法功能是愚蠢的。

所有141条评论

用例是什么? 我见过的大多数建议用法都是反模式。

单击提供的链接,您可以看到许多用例中的一些。 如您所见,许多订阅者认为它是真正有用的功能,而不是“反模式”

糟糕,现在我看到问题“#105”发生在#2105,因为根本没有任何评论了...
也许我提供了错误的链接...

因此,我发现将一些配置/初始化文件复制到容器中真的很有用。 例如,一些* .sql用于db容器的内容,一些html / js / css用于apache / nginx容器的内容,甚至Java容器的jar文件。 这将使其不仅在组成卷的机器上(如在安装卷的情况下)“全局”可用/可运行。 主要是主机本地文件和容器包含的文件的某种组合。 实际上,任何容器都可以在没有任何配置或初始化的情况下被认为是无用的

这是正确的链接: https :

+1

这将使其不仅在组成卷的机器上(如在安装卷的情况下)“全局”可用/可运行。

这样做的问题是它的视力难以置信(因此称为“反模式”),因为它将迫使您每次重新创建容器时都要重复操作。 更不用说它的伸缩性很差的事实(如果您有10个容器该怎么办?20到100个?)

解决此问题的实际方法是在构建(Dockerfile)中包含那些必需的文件,并在需要更新时进行重建。

当然,如果将包含所有“共享”内容的内容组成的容器组成,则缩放10-20-100-个容器会容易得多。 您需要做的就是从存储库中拉出它,然后仅在特定于节点的配置中挂载(是,在这种情况下是挂载)。 甚至更多,您不需要在每个节点上运行docker-compose。
当然,我们可以将docker-compose与build:和Dockerfile结合使用,但是事情变得更加复杂,并且docker-compose中的yaml配置更加“优雅”:o)

我遇到了一个问题,那就是复制会派上用场(至少作为替代)。 我主要在Mac上进行开发,因此我几乎从未见过以root身份在容器中运行并导出到已安装卷的命令的问题。 但是,最近在CentO上使用相同的工作流程引起了一些重大麻烦,因为root用户拥有的文件正通过安装的卷添加到主机。 在这种情况下,我希望能够将主机文件复制到容器中,而不必挂载它们。

相关问题:#1532

更新

我认为就我而言,我可以在Dockerfile中使用COPY并拥有多个docker-compose文件,其中一个使用卷挂载。

用例:
我想使用容器内只读文件系统中的目录。 应用程序在该目录中创建新文件,但是由于仅读取文件系统,因此会导致错误。

我不能使用rw卷,因为文件系统是只读的。
我不能使用ro音量,因为效果是一样的。

进行仅在容器运行时才持久的写操作真是太棒了。 我可以将包装器(https://stackoverflow.com/questions/36362233/can-a-dockerfile-extend-another-one)封装为仅COPY文件,但将其打包,类似于volume ,会更好

用例:从.gitlab-ci.yml同时启动多个docker容器,需要将其写入git存储库的目录。

如果容器中的进程失败,或者在容器清理完之后取消ci作业,则由于缺少权限,gitlab-runner无法删除其余文件。 现在我可以将容器中的文件从卷中复制到另一个目录,但这将是反模式,不是吗?

这与volumes: - ./folder_on_host/ :/folder_in_container/吗?
我可以通过这种方式在撰写文件中将文件从主机复制到容器(相当于COPY)

@harpratap是正确的,但是缺点是/ folder_in_container不能存在或必须为空,否则它将被覆盖。 如果您将bash脚本作为入口点,则可以在/ some_empty_location创建卷后,通过将文件符号链接到最初预期的目录中来规避此问题

+1具有COPY功能。 我们的用例是快速建立本地开发环境并复制开发设置的配置。

+1表示复制。 这确实是一个有用的功能。

用例:在集群模式下,我有一个使用mysql映像的服务。 我需要在/docker-entrypoint-initdb.d/中复制我的初始化脚本,以便MySQL可以执行它们。

虽然可以在mysql之上创建映像,复制文件并使用它或连接到mysql
大量执行任务,然后手动运行脚本,我认为这是不必要的。

为COPY / ADD +1,

用例:
Fluentd要求在运行时将配置文件移动到容器中。 这些配置文件是由我们的Jenkins Engine在运行时创建的,并且在docker中没有COPY / ADD的情况下,它只会失败。

+1即可复制

假设其中一个在多个Docker机器上具有共享的配置文件,并且它们的Dockerfile位于docker-compose目录下的相应子目录中。 如何将共享配置复制到每个映像中? 我不能从Dockerfile上下文中象征性地链接到../ ,而不会得到COPY failed: Forbidden path outside the build context

在这种情况下,当运行docker-compose构建时,我想在运行docker build步骤之前从docker-compose上下文中复制配置文件。

如果有人可以提出一个干净的解决方法,我很高兴。

拥有功能会很棒!

请不要只用+1进行评论-这是浪费每个人的时间。 如果您需要提供其他信息,请这样做; 否则,只需对原始问题表示赞赏。

仅仅因为在某些情况下最终会引起问题,教条上坚持说它是反模式的用途是什么? 这肯定有很好的用处,因为您可以在现有文件中添加一行,而不必创建额外的文件夹和文件,然后将要添加的文件移动到那里。 微小文件的这种毫无意义的官僚创建是真正的反模式,可防止用户创建简单且易于维护的docker-compose文件。

如果用户想使用Docker做有害的事情,无论您做什么,他们都会找到一种方法。 仅仅因为某天可能滥用某些功能而拒绝添加合法功能是愚蠢的。

在这种情况下,我认为您正在做的事情实际上是正确的方法。

这里提出的问题更像是,假设mongo.conf文件在由一个docker-compose文件编排的三个docker映像之间共享。 如何确保每个docker build子目录中的相同?

例如,如果您使用符号链接,则docker会抱怨该文件在构建环境外部,例如docker build缺乏可重复性,因为对该目录外部的修改可能会更改构建。

因此,唯一的协调方式是使用文件副本,该文件副本当前需要在运行docker-compose之前使用Makefile或shell脚本来完成,因此讨论这是否是docker-compose可以使用的功能似乎是一个主意当然,这肯定是常见的用例。

您提出的问题似乎与本地文件修改的运行时(启动时)注入有关。

我认为您实际上在做事上很好,上面所说的只是做事方法。 可以始终将docker映像构造为接受环境变量来回答诸如config目录在哪里的问题,并且可以在运行时使用卷“注入”该配置目录-但这要取决于docker映像的设计环境变量和卷映射(这是docker在运行时配置修改时支持的功能。)

希望我不会误解您的评论,希望我的回复对您有所帮助。

@jpz-我不知何故删除了我的原始评论-yikes-对不起! 谢谢-是的,这很有帮助。

我最初的评论是:

我的用例是我想使用mongo声明服务,而不必创建自己的自定义映像,而只是复制诸如/etc/mongod.conf的配置文件。

更新:我使用volumes 。 一两年前-我以为我曾以一种糟糕的经历尝试过此方法……但似乎还不错。

+1即可复制

我为此创建了一个要点。 假定docker compose服务的名称为phpfpm ,但是您可以将其更改为所需的名称。 随时修改。
https://gist.github.com/markoshust/15efb29aa5eebf8adae402af18b2e674

您好,我想知道这个问题的进展如何。 现在,我将Windows 10 home与docker-toolbox一起使用。 当我尝试将文件作为卷装入容器时,这似乎主要是错误。 最好在docker-compose中具有COPY功能

COPY / ADD绝对是受欢迎的功能。

一个用例:出于开发目的,在Docker中运行Graylog实例。 为了自动启动输入,必须将JSON规范放入/ usr / share / graylog / data / contentpacks
有了COPY / ADD功能,它就像YML中的单行一样容易。

为了使其现在能够正常工作(2018年10月16日),需要将卷安装到该点并将该文件夹的原始内容复制到永久卷。 这是安静的不便。

我将从中受益,我有一套工具可以将数据库种子导入到容器中,然后基于该文件运行devtools数据库导入器。 我不想做:

docker cp "${seed_file}" $(docker-compose ps -q devtools):/tmp/seed_file

才能进口我的种子。 不,我不会使用固定的架构来编译我的开发映像,这至少与Web开发模式背道而驰。 容器应确保应用可移植性,而不是数据。

这样做更有意义:

docker-compose cp "${seed_file}" devtools:/tmp/seed_file

总而言之,基本上只是做相同事情的简写,但在各处利用docker-compose似乎比混合东西更好...

1)这似乎是#3593的重复项
2)我同意@ shin-精心设计的用例遵循反模式
3)但包装Docker的cp命令很有意义,imo

@funkyfuture如果您认为这些用例遵循反模式,那么请提出一个不建议使用的解决方案。

类似于k8s的“数据段”呢?
例如:

services:
  service1:
    image: image.name
    data:
      filename1.ini: |
        [foo]
        var1=val1
        [bar]
        var2=val2
      filename2.yml: |
        foo:
          bar: val1

或可能相同,但对于volumes:部分

volumes:
  service_config:
    data:
      filename1.ini: |
        [foo]
        var1=val1
        [bar]
        var2=val2

services:
  service1:
    image: image.name
    volumes:
      - service_config:/service/config

@胫-

这样做的问题是它的视力难以置信(因此称为“反模式”),因为它将迫使您每次重新创建容器时都要重复操作。 更不用说它的伸缩性很差的事实(如果您有10个容器该怎么办?20到100个?)

这里的实际问题是,某些人过于急于提供所需的功能,因为它与他们对实际用例场景的有限视野相冲突。

在这里,我正在寻找一种将配置文件复制到我刚从dockerhub获得的容器的方法。 我没有访问原始Dockerfile的权限,拥有此功能将为您带来极大的便利((而不是尝试在顶层构建另一层,虽然可以工作,但是不方便,但我不想在更改某些内容时进行重建)。

用例:

我在集成测试环境中运行数据库,并希望在启动容器时在每次迭代中重置数据。 将数据嵌入自定义映像中是可以的,但是装入卷很麻烦-因为必须重置主机上的数据。

我们独立维护数据,仅使用标准数据库映像-在数据开始运行之前将数据复制到其中将是最方便的。 目前,docker-compose似乎无法实现。

我有一个用例。 我想基于现成的映像(例如通用Apache服务器)创建映像。 我想在图像创建过程中复制我的html。 这样,我可以随时更新基本映像,而copy指令将确保我的内容包含在新映像中。

顺便说一句,我目前在docker-compose.yaml中使用dockerfiles和一个build指令来做到这一点。 如果我不需要docker文件,那就太好了。

@tvedtorama-

用例:

我在集成测试环境中运行数据库,并希望在启动容器时在每次迭代中重置数据。 将数据嵌入自定义映像中是可以的,但是装入卷很麻烦-因为必须重置主机上的数据。

我们独立维护数据,仅使用标准数据库映像-在数据开始运行之前将数据复制到其中将是最方便的。 目前,docker-compose似乎无法实现。

本期讨论在映像构建时而不是在运行时复制文件的愿望。 我建议单独提出一张票以讨论其优缺点? 它可能会使讨论变得混乱,而转移到讨论运行时文件注入(我将解释您在说什么)。

@ c0ze-

类似于k8s的“数据段”呢?
例如:

...

我尚未完全了解该配置的功能,但是可以,这似乎是一个解决方案。 从根本上讲,当您有秘密时(例如,登录用户名/密码/数据库的端口是什么),如何在不编写代码负载的情况下将其注入到我的docker映像(客户端和服务器)中?

像kubernetes数据节之类的东西可能会起作用-因为它将是事实的单一来源。 否则,可能会发现它们在多个docker映像中具有多次维护的相同秘密。

那里也有现有技术,这有助于将对话推进到实际上是否是一个值得采纳的好主意。

对我而言,这一切都始于希望在容器之间共享不变的配置文件,并且意识到没有外部脚本编写到docker-compose的方式,并且将配置从单一事实来源写入每个配置中,就无法做到这一点。 docker-compose文件夹下面的Docker文件夹。 当然,我得到了Docker的不变性参数(例如Dockerfile目录完整,完整地描述了如何构建映像),因此,要求自动化将内容复制到该目录中似乎有点不符合这些原则。

我猜这里的讨论是docker-compose被允许有多侵入性? 这是足以证明这种自动化合理性的通用用例吗? 如果不是这样,那么我们似乎负担了环境变量传递机制的负担,要负责从一个事实真相中(例如在运行时)从外部向外界注入秘密,我希望我的观点在这里足够连贯。

这对我来说意义不大,但是我认为用例值得讨论。

这对我来说非常有用。 在工作中,该病毒软件阻止了Windows 10与容器共享卷的功能。 这是一个庞大的组织,并且由于另一大洲制定的政策而让他们进行更改不是初学者。

您好,我的用例:我正在使用开源Prometheus docker-compose安装程序(存储库由其他人维护)。 它具有安装到容器中的配置。 问题:我无法在远程机器(例如aws docker机器或CI / CD运行器内部)上进行docker-compose,因为它无法正确安装配置。 在这种情况下,我想复制/嵌入它们。 对于RW数据,有容量,对于RO-?

另一种选择是让RO卷具有设置初始数据的可能性。

当前解决方案:通过ssh连接到docker主机,克隆/更新仓库并运行docker-compose up。 这适用于手动情况,但是对于自动化来说很痛苦:(

+1

用例:我有一台运行数据库的开发docker机器,每当我设置它时,都需要安装数据库的最新转储。 有效地意味着:

  1. 从extern中提取数据库docker镜像。
  2. 将ZIP复制并解压缩到运行的图像中。
  3. 在卷内执行db-restore。
  4. 删除数据库转储。

现在最大的问题是,每个开发人员的步骤2总是不同的,因为该数据库有许多不同的转储版本,所以最简单的方法是,每个开发人员都有自己的撰写文件及其特定的转储位置/版本,然后让docker在构图时将图像与该特定文件位置组装在一起,然后在需要其他版本时也可以即时更改。

我的用例很简单。 我既不想卷,也不想滚动自己的图像。 我只想在配置文件创建之后和启动之前将配置文件的简单防御性副本放入容器中。

这还是个问题吗?
我的django应用程序的设置文件很长。 对我来说,创建docker映像并将单个配置文件复制到每个容器会更容易。
将所有设置作为ENV传递对我来说是反模式。 需要大量代码,难以维护,并且可以使用单个copy命令解决。

我打开了#6643,希望获得有关如何将其视为反模式的反馈。 尤其是在可能需要即时添加/修改大量配置文件的环境中。

@胫-

这样做的问题是它的视力难以置信(因此称为“反模式”),因为它将迫使您每次重新创建容器时都要重复操作。 更不用说它的伸缩性很差的事实(如果您有10个容器该怎么办?20到100个?)

如何在多个容器中使用docker-compose exec

    --index=index     index of the container if there are multiple
                      instances of a service [default: 1]

我们不应该尝试使用cp获得相同的行为吗?

恕我直言, execcp一样短暂。 但是无论如何我总是认为它是“开发”命令,开发环境必须是短暂的,不是吗?

我在这里没有看到有关许多开发人员的评论,他们说他们是近视眼的,他们试图通过请求此功能过快地解决此问题。 我认为这有点苛刻和屈尊。 如果我从我的多年发展中学到的一件事是:

不是您的软件做什么,而是用户使用它所做的重要

显然,我知道您可以防止事情发疯,但这并不是因为有人根据您的设想错误地使用了工具,因为每个人都会以这种方式开始这样做,而所有的地狱都会崩溃。

我在这里看到的所有特殊情况在大多数时候都是非常合适的。 而且,大多数这些特殊情况都不应该在生产系统上发生,例如,就像我之前解释过的情况一样,它们是自定义开发环境并在无法使用的容器中运行特殊文件卷映射。 大多数示例清楚地表明,它们不希望烘焙架构,数据或配置文件,并且不能使用卷映射,因此我不明白为什么这么多的麻烦之处还在于使用“短视”一词。

我想您在说这样的话时应谨慎加重言语...

  1. 我真的不需要就我可以说或写的内容进行演讲。 对不起,“近视”会冒犯您。 准确地说,这些东西是设计使然属于Dockerfile的。
  2. 我不再是维护者了。 请在我无法控制的事情上停止@ -ing我。
  1. 我不得不在这里说我支持crazycodr的一面...将完全有效的现实用例视为“反模式”,而没有给出有用的实践和现实选择是开发人员不友好的方式,说实话甚至有点粗鲁。
  2. 不管是否是维护者,如果您参与了github的讨论部分,那么您基本上都必须与别人一起评论您的评论。 这就是它的工作原理。 处理...

让我们把它带回来。 诚实的技术问题在这里。 使用docker stack,我们有一个“配置”选项。 这是本机docker功能,但用于服务而不是容器。 在容器级别而不是服务级别获得类似功能的可行性是什么? docker stack如何实现配置设置? 可以专门为docker-compose复制该实现吗?

至少这里提到的用例中有一半是关于配置的,所以如果只痒痒痒,那么很多人都会感到满意。

另一个简单的用例是Google域名验证之类的东西。 如果您使用wordpress图片,则无法添加Google将检查的文件。 您需要制作一个全新的图像。

同样,这些评论说事物是“反模式”,这是没有道理的,是精英主义的产物。

编辑:yikes,阅读更多,感谢上帝,他不再是维护者了

因此,您告诉我,如果我想将一个微小的配置文件复制到预构建的映像中(例如nginxmariadb ),我现在需要管理自己的映像构建设置并复制使用的磁盘空间(原始映像和配置的映像)?

这应该是一个功能。

复制使用的磁盘空间

您不是在使用Docker时。

我喜欢您从他所说的话中挑剔一件事,这是所有事情中最次要的事情。 这应该是一个功能。 由于这是一个常见的用例,这个问题将随着人们随着docker的发展而不断增长,并且人们只会期望它的存在是基于常识,而维护者以前和现在的情况似乎都缺乏。

我喜欢您从他所说的话中挑剔一件事,这是所有事情中最次要的事情。

应该指出一个无效的论点。

我认为这里的事情是,“反模式”参数可以在给定某种业务策略的情况下有效(请参阅@washtubs点)。 我们可能不同意这种策略,但这不能证明有人为攻击。 最终,这是@ shin-过去在docker-py方面的努力,这使您可以实现docker-compose的替代方案。

什么是“反模式”论点? 没有论据。 这只是一个“不,因为反模式”,其背后没有任何逻辑,只是说了一下而没有任何备份。 就像人们说的那样,他们想到了最坏的情况,认为该情况是一种反模式,然后甚至不写任何所谓的反模式情况就将其视而不见。

这只是精英主义。 这里的许多评论都是关于不添加此内容的理由多么荒谬,它们都被忽略了。

常识和逻辑与您的感情或精英无关。 或您制作的反模式。

是的, @ robclancy ,请将其保留为民用FFS。 我想要这个功能,但是如果您要做的就是在维护人员面前说废话,请发泄Reddit。 完全有必要@funkyfuture的更正。

最终,这是@ shin-对docker-py的过去努力,它使您可以实现docker-compose的替代方案。

如果您要这样做,我显然不希望使用docker-compose的分支,特别是对于这么小的增强功能。 这是发生这种情况的唯一其他方式,这对社区不利。

如果有人提交了PR,是否真的会考虑? 还是由Docker撰写团队坚决决定不接受的东西? 您会考虑添加与docker stack configs兼容的config节吗?

这已经脱离了轨道……没有解释的“反模式”将“反模式”变成了一个非常宽泛的定义,这是无法反对的。 也没有明确的方向说明“反模式”位于哪一侧。 docker或docker-compose。

明确定义反模式响应将是非常棒的,并且将不胜感激。

社区将继续增长,因此需要存在一套既定的定义。

我想用它来复制在docker compose堆栈上运行的jenkins管道生成的工件。 然后,容器名称可以是随机的,因此我不能使用docker cp

今天我必须使用

docker cp $(docker-compose -f docker-compose.development.ci.yml ps -q test):/app/tests_output ./tests_output

这与volumes: - ./folder_on_host/ :/folder_in_container/吗?
我可以通过这种方式在撰写文件中将文件从主机复制到容器(相当于COPY)

我正在尝试这样做。 我有一个包含csv文件的文件夹,我想将其提供给logstash。
我怎样才能做到这一点。 还是容器中的哪个文件夹?
目前,我有一些东西:
./path/至/ storage :/ usr / share / logstash /

任何的意见都将会有帮助

@ shin-这张票已经1.5岁了。 当有160个人告诉您您错了-您可能是错的。

您还需要什么说服您执行此操作?

不听客户意见的公司

@ shin-这张票已经1.5岁了。 当有160个人告诉您您错了-您可能是错的。

💯🥇😲

也,

我不再是维护者了。 请在我无法控制的事情上停止@ -ing我。

@sfuerte有一个名为Kubernetes的小项目已经取代了Docker-Compose。 我想知道如果对用户反馈的态度更加积极是否会发生这种情况。

我们需要一个流行语来反击他们的流行语。 这就是他们所能应付的一切。

此功能将完全是pro-pattern 。 那应该做。 区别在于,即使我犯了这个愚蠢的问题,在本期中仍有许多评论以明显常见的用例的方式显示了其优点。 而且没有anti-pattern的单个实例。

@ shin-之所以被加标签,是因为您在没有实际依据的情况下开始了此胡说八道的反模式废话。 因此,不要再为您造成的事情而哭泣。

k玩得开心

我的情况是:

  • 在“ dev”期间,我希望将我的源代码构建为“ volume”,以便在开发过程中自动更新
  • 当应用程序准备发布时,我需要“部署”,我想复制复制的文件,而不是卷。

我认为解决此问题的最简单方法是为dev创建1个撰写文件,为生产使用1个撰写文件。

这里的问题是我可以在docker文件上指定“ volumes”,但不能在docker file上指定“ copy”?

有人和我一样吗? 我想念什么吗?

@ shin-这是反模式吗? 您将如何解决这个问题?

@hems ,在理想情况下,您希望将应用程序部署为独立的docker映像。 因此,如果您正在编写应用程序,则打算部署的源代码可能应该是Dockerfile ,因此映像包含整个应用程序。 因此,在Dockerfile ,如果您想要/ var / www中的源,则可以放

COPY my-app-src /var/www

您的来源不是特定于环境的,因此仅属于docker映像。 简单。

我们大多数人都希望在容器中包含一个特定于环境的配置文件,以使现有映像与特定的docker-compose配置一起正常工作。 而且我们希望能够做到这一点,而无需为小文件创建卷或滚动新图像。

泊坞窗组成团队中的某人能否请认真认真地看待这一点并得出最终裁决(希望该裁决会忽略所有未成熟的人)? 这个问题已经永远公开了。 结果很重要,但就我个人而言,我已经厌倦了收到通知。

COPY my-app-src /var/www

这就是我的意思,在开发中,我想使用docker-compose文件将VOLUMES挂载到映像中,而在生产构建期间,我想将文件复制到映像中,因此为什么我认为我们应该能够复制并挂载VOLUMES使用docker-compose文件,因此我可以为dev创建1个compose文件,为生产构建1个。

我在维护Compose的团队中工作,很高兴参加这个讨论。 首先,我将概述我们如何看待Dockerfile和Compose文件的职责。

Dockerfile是构建映像的方法,应添加使服务正常运行所需的所有二进制文件/其他文件。 对此有两个例外:机密(即:凭据),配置(即:配置文件)和应用程序状态数据(例如:您的数据库数据)。 请注意,秘密和配置是只读的。

撰写文件用于描述一组服务的部署和交互方式。 Compose格式不仅用于单个引擎(即docker-compose ),而且还用于Swarm和Kubernetes之类的协调环境。 Compose格式的目标是使编写应用程序和在本地进行测试变得容易,然后将其部署到经过精心编排的环境中,而几乎不需要更改。 这个目标限制了我们可以更改格式的内容,原因是存在根本差异,例如每个环境如何处理卷和数据存储。

像这样减少Dockerfile和Compose文件的职责,可以使我们很好地分离关注点:每个容器映像(Dockerfile)中的内容,服务的部署和交互方式(Compose文件)。

现在,我将遍历图像中存储的每个异常。 对于秘密,您不希望将它们烘焙成图像,因为它们可能会被盗,并且因为它们可能会随着时间变化。 Docker Secrets用于解决此问题。 这些工作原理略有不同,具体取决于您部署到的环境,但是从本质上讲,您可以将凭据存储在一个文件中,该文件将在运行时以只读方式挂载到容器中的tmpfs目录中。 请注意,该目录将始终为/run/secrets/ ,并且文件将为密钥的名称。 Swarm,仅引擎( docker-compose )和Kubernetes支持秘密。

对于配置文件或引导数据,有Docker Configs 。 这些工作与机密类似,但是可以安装在任何地方。 Swarm和Kubernetes支持这些,但是docker-compose 。 我相信我们应该增加对这些的支持,这将有助于解决本期中列出的一些用例。

最后,有应用程序状态数据需要存储在外部。 我不会深入探讨这个问题,因为它与这个问题无关。

有了这个框架,我可以回答几个问题:

  • 我们是否将copy字段添加到“撰写”格式? 不,我认为我们不会这样做,因为在精心设计的环境中这没有意义。
  • 我们将在docker-compose添加configs支持吗? 是的,我认为我们应该这样做。
  • 我们将添加docker-compose cp吗? 也许,我还不确定。 它实际上是docker container cp的别名。

鉴于此,可以在此处使用几个工具:

  • 多阶段构建允许您使用目标有条件地将文件添加到图像。
  • 允许您在运行时将凭据传递到服务的机密。
  • 允许您在运行时将配置信息传递到服务的配置。

我认为那些工具解决了该线程中提出的所有问题。

这条线很热。 请记住,每个GitHub句柄背后都有一个真实的人,他们可能正在尽力而为(即使他们的挫败感正在显现)。 我们都对Compose充满热情,并希望该项目继续蓬勃发展。

我们将添加docker-compose cp吗? 也许,我还不确定。

我会发现像docker-compose exec这样的实用便利。

@ chris-crone惊人的回复,谢谢!

我知道我并不能代表所有人,但是我得到的印象是, configs支持可以满足这里的大多数需求。 为此应该开一个问题吗?

感谢您提供一些替代方法。 到目前为止,我还不了解多阶段构建。

我得到的印象是, configs支持可以满足这里的绝大多数需求。

我对此表示怀疑,因为我怀疑这里的大多数人没有使用Swarm和afaik的config功能需要这样做。

是的,目前需要Swarm,但来自@ chris-crone的评论...

Swarm和Kubernetes支持这些,但docker-compose不支持。 我相信我们应该增加对这些的支持,这将有助于解决本期中列出的一些用例。

...我读到这可以在docker-compose(sans Swarm)中实现

Compose格式的目标是使编写应用程序和在本地进行测试变得容易,然后将其部署到经过精心编排的环境中,而几乎不需要更改。

在复杂的应用程序中,我们可能有很多配置文件需要即时调整。 现在,最有效的方式(在时间和成本方面)是填充音量键(因为没有理智的人会在测试多种配置时创建不同的图像。.除非他们有一个只喜欢花钱的老板)在开发时间)。

Swarm和config并不能真正回答列出的几个用例。 “关注分离”也不适用,因为compose已经可以在docker中完成,但是可以简化它。 包装器不是分离的...我们只是想让您再扩展一点...

https://github.com/docker/compose/issues/6643

扩展它的功能,其中新密钥下的每个文件都动态链接到单个卷,并映射到它们各自的内部路径...

我认为这里有两种情况非常有效,一种是关于
开发环境。 人们用源创建灵活的环境
代码安装到其图像中。 源代码随着开发而发展
发生并且您无法不断重建图像,或者只是浪费
大量的时间。 完全是我的情况,我可以看到
该方案适用于很多其他人。

第二个是关于烘烤源代码的生产图像
(以防您使用非编译脚本)到映像中(以及
再一次,我不是,我仍在将它安装在我的身边)或者你只是
编译您的应用程序并将其复制到最终映像中。 在那时候,
该应用程序变得非常便携。

我想每个人都明白! 问题是,做docker-compose
开发人员花时间阅读案例并了解需求? 有
从理论上讲,这里没有反模式,只有有需要并且愿意
被尊重。

我们喜欢docker,docker-compose和所有生态系统,我们之所以使用它,是因为我们
喜欢它,并且因为我们使用它,所以您有工作(至少有些人有薪
为此,我希望)。

过去几年我学到的一些东西,我喜欢带回这里,
有以下内容,它非常适用于这种情况:

关键不是您的软件做什么,而是您的用户做什么
重要的是

欢呼和幸福的连续性!

在2019年6月6日星期四10:55,jadon1979 [email protected]写道:

Compose格式的目标是使编写应用程序变得容易
并在本地对其进行测试,然后通过以下方式将其部署到协调的环境中:
几乎没有变化。

在复杂的应用程序中,我们可能有很多需要的配置文件
快速调整。 目前最有效的方式(时间和成本明智)
这样做是为了填满音量键(因为没有理智的人要走
在测试多个配置时创建不同的映像。
他们有一个只喜欢在开发时间上花钱的老板)。

Swarm和config并不能真正回答几个用例
列出。 “关注分离”也不适用于已经撰写的
做您可以在docker中做的事情,但简化了它。 包装器不是
分离...我们只是想让您进一步扩展...

6643 https://github.com/docker/compose/issues/6643

用它来破解..扩展卷功能,其中下的每个文件
新密钥动态链接到单个卷并映射到它们的
各自的内部路径...

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/docker/compose/issues/5523?email_source=notifications&email_token=ABBR3OMQH62242SM4QN5Y7TPZEQP7A5CNFSM4EKAVONKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLO
或使线程静音
https://github.com/notifications/unsubscribe-auth/ABBR3OMOZFZ47L6ITHPF2TDPZEQP7ANCNFSM4EKAVONA

我想启动一个docker Tomcat环境,以从一个名为ROOT.war的.war中运行我的应用程序。 为此,我必须将其复制到Tomcat的webapps目录中,并将其重命名为ROOT,以便它将在当前绑定的端口8005/9上运行。 由于端口上的重新绑定问题以及有关“非法访问”的错误,其他所有操作均失败。 这些是临时测试版本,因此无法在Dockerfile中使用。 这就是为什么我要在docker-compose

@washtubs

我知道我并不能代表所有人,但是我得到的印象是,配置支持可以满足大多数人的兴趣。 为此应该开一个问题吗?

如果还没有问题,请创建一个并在此处链接。 我在我们的私人团队追踪器中添加了一些内容。

@washtubs @funkyfuture

...我读到这可以在docker-compose(sans Swarm)中实现

我们已经有了基本的秘密支持,并且可以通过类似的方式来实现配置。

绝对是缺少的功能。 唯一的“反模式”是您必须解决以下事实:通过其他方法很难做到这一点,例如更改dockerfile的入口点脚本,或将挂载文件绑定到容器中。

您想要的是一个在使用时即docker-compose可一次构建(最好是正式构建)并且可针对用例进行配置的容器。

据我所知,码头工人没有意识到的是,“ Dockerfile”是整个码头工人概念中最大的反模式,特别是因为整个事情是完全不可读和不可维护的。 当与docker相关的任何人扔出他们想知道的“ antipattern”一词时,这真的让我发笑!

Dockerfile实际上阻止了正常的调试和整理,如果您使用了构建脚本,或者实际上是为构建东西而设计的东西(例如……包管理器或make),则可以进行调试和整理。

就我自己而言,我在所有用例中都使用相同的DockerFile(使其成为一种模式!)建议我去为每种不同的用法更改DockerFile,这确实是反模式。

而且没有“配置支持”根本不会削减它,而是在不需要的地方施加了结构。

根本的问题是,如果将mount绑定为说/ etc / nginx,则必须rw允许脚本运行以调整配置(也称为envsubst)。 然后,这将更改输入配置(需要保持不变)...您不会获得比容器在其整个配置上写入更多的反模式,因此需要在重新创建时将文件复制到容器中的选项解。

换句话说,它是容器中的绑定安装目录rw,但在主机上是ro。 认真地允许你这样做会杀死你吗?

绝对是缺少的功能。 唯一的“反模式”是您必须解决以下事实:通过其他方法很难做到这一点,例如更改dockerfile的入口点脚本,或将挂载文件绑定到容器中。

您想要的是一个在使用时即docker-compose可一次构建(最好是正式构建)并且可针对用例进行配置的容器。

据我所知,码头工人没有意识到的是,“ Dockerfile”是整个码头工人概念中最大的反模式,特别是因为整个事情是完全不可读和不可维护的。 当与docker相关的任何人扔出他们想知道的“ antipattern”一词时,这真的让我发笑!

Dockerfile实际上阻止了正常的调试和整理,如果您使用了构建脚本,或者实际上是为构建东西而设计的东西(例如……包管理器或make),则可以进行调试和整理。

就我自己而言,我在所有用例中都使用相同的DockerFile(使其成为一种模式!)建议我去为每种不同的用法更改DockerFile,这确实是反模式。

而且没有“配置支持”根本不会削减它,而是在不需要的地方施加了结构。

根本的问题是,如果将mount绑定为说/ etc / nginx,则必须rw允许脚本运行以调整配置(也称为envsubst)。 然后,这将更改输入配置(需要保持不变)...您不会获得比容器在其整个配置上写入更多的反模式,因此需要在重新创建时将文件复制到容器中的选项解。

换句话说,它是容器中的绑定安装目录rw,但在主机上是ro。 认真地允许你这样做会杀死你吗?

像这样:

```

如果文件则覆盖

如果目录,则覆盖/附加目标内容

使用源中的内容来维护原始目标结构

来源:文件:p权限:所有者:组

svc:
复制:
-'./source/ filename:/ path/
-'./source/ dir:/ path/

# 要么
svc:
复制:
-来源:“ ./ source / file”
目的地:“ /目的地”
许可:ro
所有者:所有者
组:组
-来源:“ ./ source / directory”
目的地:“ /目的地”
许可:ro
所有者:所有者
组:组```

用例:我们有一个无序的容器解决方案,其中包含应用程序的docker-compose文件,包括。 Git储存库中的SSL证书等,并将其拉到VM上。 然后,我们启动服务,并希望将SSL证书,配置文件等移至容器的卷中。 当前,如果没有随附的带有COPY命令的Dockerfile,这是不可能的。 我们不想弄乱克隆的git repo中的文件。 如果应用程序会更改文件,则我们每次都必须清理存储库。

@MartinMajewski然后可以将带有证书的目录作为卷装入目录,并将其指向应用程序配置。

用例(以及如何立即提问):
我有postgres图像,并且在开始时设置了一个环境变量: POSTGRES_PASSWORD 。 我想通过Docker Secret进行设置。 我需要做的就是将我自己的entrypoint.sh放入附件中,将Secret导出到运行容器的env var中。 我需要在启动时以某种方式将此入口点添加到我的容器中。 没有两行Dockerbuild –我不能。 只能复制一个文件–无法完成。

PS postgres是一个示例。 假设它不支持_FILE env vars。

用例:Karaf
使用我不想在每次构建项目时都进行重建的karaf基本映像,我希望能够快速部署应用程序并为每次构建都重建容器。 但是,启动容器时,我需要将_features.xml_和_jar_复制到deploy目录中。

到目前为止,我的解决方案是将karaf映像用作另一个Dockerfile(依赖于overlayfs的基础映像),该文件最终会耗尽叠加层,从而强制手动删除该映像)和avast / gradle-docker-compose-plugin。 尽管可以肯定地将init命令作为环境变量进行传递,但features.xml的内容却不能。 它必须作为文件存储在容器中的特定位置。 现在,我只能使用卷绑定安装来执行此操作。 如何将东西放入远程计算机的该卷中? 我的构建脚本中还需要更多逻辑(例如org.hidetake.groovy.ssh,这还会使构建脚本与秘密密码/密钥逻辑复杂化)。 如果可以使用docker-compose cp,则可以将必要的复制命令添加到docker-compose.yml中。 avast / gradle-docker-compose-plugin将处理容器的构建并将文件从构建输出直接复制到容器中,而无需任何额外的远程文件系统访问逻辑。

该Dockerfile被添加到脚本的docker-compose.yml构建部分。 如果有的话,这是一种反模式,因为它只会在每次构建时向上游docker镜像添加覆盖(直到我被迫手动删除该镜像,这会使构建速度变慢)。

FROM myregistry:443/docker/image/karaf-el7:latest

COPY karafinitcommands /usr/local/karaf/etc/

COPY features.xml \
     *.jar \
     /usr/local/karaf/deploy/

我发现令人沮丧的是docker cp可以很好地用于运行时复制,但是docker-compose没有等效的机制。

我以为是将本地目录绑定到/ usr / local / karaf / deploy并将文件放在那里。 我不希望必须重建映像或使用docker文件来避免这种情况。

我以为是将本地目录绑定到/ usr / local / karaf / deploy并将文件放在那里。 我不希望必须重建映像或使用docker文件来避免这种情况。

这样肯定是可以实现的。 重读并注意到这纯粹是一个方便的问题:容器通过gradle build进行了重建,下一步的逻辑步骤是:如何将新的build文件移动到/ usr / local / karaf / deploy中安装的“本地目录”中? 在我的情况下,“本地目录”更准确地说是主机是远程主机的“主机目录”。 因此,我必须在构建脚本中添加rsync或其他内容,以使文件在那里并确保替换了旧文件,并删除了多余的文件。 如果docker-compose cp可用,则没有必要。 我可以利用现有的docker客户端到docker daemon的连接,该连接是通过端口转发设置的。

可以在每个版本中删除Docker卷。 绑定安装卷不能。 仅当它们为空时,才会重新填充

同样,可以使用docker cp将文件复制到运行时环境。 那是令人沮丧的部分。

啊,好的,我也已经习惯了自己的设置。 我使用http://github.com/keithy/groan一个bash脚本,该脚本将零碎的部分自动部署到远程服务器,然后调用docker。

用例:Google Cloud构建和构建工件

需要工件:Web客户端(自动生成)响应graphql绑定。 您需要运行服务器来创建客户端编译所需的文件。 客户端映像具有在给定服务器地址的情况下创建绑定的工具。 因此,您需要在背景中启动服务器映像,现在需要运行指向服务器的客户端容器。 现在如何将生成的文件从容器中取出,并进入“工作区”主机目录中? 不允许挂载目录,因为您已经在docker容器中的挂载目录中。 能够docker-compose cp可以减轻获取容器ID的额外痛苦。

依靠$(docker-compose ps -q SERVICE)来定位正确的容器,可以将无格式docker cli用于此类以容器为中心的操作。 引入新命令肯定会使要求它的少数用例更简单,但这不是必需的。 为了避免在compose和docker CLI之间进行更多的代码重复,我认为应该解决此问题。

一个开放的问题是,由于compose使用的docker守护程序版本不同,compose和普通docker之间的构建缓存有所不同,这意味着您需要使用pure compose才能在CI环境中不破坏缓存(https:// github (.com / docker / compose / issues / 883),因此在解决这些问题之前,将普通docker命令与compose命令混合使用会中断缓存。 compose配置指定各种在config中进行的烘焙,从而减少了使用简单的docker命令手动指定重复配置的需要。

依靠$(docker-compose ps -q SERVICE)来定位正确的容器,可以将无格式docker cli用于此类以容器为中心的操作。 引入新命令肯定会使要求它的少数用例更简单,但这不是必需的。 为了避免在compose和docker CLI之间进行更多的代码重复,我认为应该解决此问题。

这比“很少提到用例”要深入得多,因为这些场景相当普遍,并且修改,构建映像,再次修改,构建映像等是可以通过docker-compose处理这些事情的耗时诗句。 “您可以在docker cli中做到这一点,所以就在那做”的说法几乎使已添加到docker-compose的许多其他内容无效。

这个问题已经开放了将近一年,在此问题之外还有很多其他讨论。 除非已解决,否则绝对不应将其关闭。

@dionjwa #883确实需要调查(如果仍然相关),因为docker-compose应该与docker CLI保持一致。

@ jadon1979我不是要阻止此功能请求,只是注意到它已经在一年多以前打开了,而且没有一个核心维护者认为引入新命令足够重要,贡献者也没有为该命令提出PR它。
我只是说,根据对此功能请求的反馈,并且缺乏开发工作以提供“更好的方式”,建议的解决方法是结合使用docker-compose和docker cli,您可以轻松地将其别名为您的环境要保持简单易用,这是一个合理的解决方法。
现在,如果有人打开PR提供新的cp命令,我将很乐意进行审查。

没有人贡献,因为每个人都被告知每个用例都是
反模式。 每隔几天我们就会发布新的用例,没有
反模式。

在2019年11月18日星期一下午5:31 Nicolas De loof [email protected]
写道:

@dionjwa https://github.com/dionjwa#883
https://github.com/docker/compose/issues/883确实需要
已调查(如果仍然相关),因为docker-compose应该与
docker CLI。

@ jadon1979 https://github.com/jadon1979我不是想阻止它
功能要求,只是注意到它已于一年前开放,并且
没有一个核心维护者认为它足够重要
引入新的命令,贡献者也没有为其提出PR。
我只是说,根据对此功能要求的反馈,
提议的开发工作不足以提供“更好的方式”
结合使用docker-compose和docker cli的解决方法
可以轻松地在您的环境中使用别名以使其易于使用,这是一个
合理的解决方法。
现在,如果有人打开PR提供新的cp命令,我很乐意
复习一下。

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/docker/compose/issues/5523?
或退订
https://github.com/notifications/unsubscribe-auth/AAGRIFY7CULCUS3TDDTTHZLQUL3TZANCNFSM4EKAVONA

我的用例不是将内容复制到容器中,而是在容器运行后复制它们。 可以通过CLI使用笨拙的解决方法来完成此操作,该

我是一名DevOps工程师,我非常依赖容器来替代裸机构建代理的依赖地狱。 当我的CI系统测试一个存储库时,它首先从同一存储库中的Dockerfile构建,然后在container_内运行所有检查( bundle exec rspecnpm test等)。 如果有创建的构建工件(如文档或测试结果),我只需使用docker cp将它们复制到容器外。

对于集成测试,我们已经开始使用docker-compose向运行测试的容器提供服务依赖项(例如数据库服务器)。 不幸的是,在这种情况下,“ docker CLI解决方法”对复制文件的作用较小。

考虑以下配置: docker-compose-minimal.yml

version: "3"
services:
  artifact-generator:
    image: busybox

我将创建容器,在该容器中运行命令,获取容器ID,然后尝试使用docker cp提取文件

$ # Prepare the images and (stopped) containers.  In this case there is only one.
$ docker-compose --file docker-compose-minimal.yml up --no-start
Creating network "docker-compose-cp-test_default" with the default driver
Creating docker-compose-cp-test_artifact-generator_1 ... done
$ # Determine the ID of the container we will want to extract the file from
$ docker-compose --file docker-compose-minimal.yml ps -q artifact-generator
050753da4b0a4007d2bd3514a3b56a08235921880a2274dd6fa0ee1ed315ff88
$ # Generate the artifact in the container
$ docker-compose --file docker-compose-minimal.yml run artifact-generator touch hello.txt
$ # Check that container ID again, just to be sure
$ docker-compose --file docker-compose-minimal.yml ps -q artifact-generator
050753da4b0a4007d2bd3514a3b56a08235921880a2274dd6fa0ee1ed315ff88
$ # OK, that looks like the only answer we're going to get.  Can we use that to copy files?
$ docker cp $(docker-compose --file docker-compose-minimal.yml ps -q artifact-generator):hello.txt ./hello-artifact.txt
Error: No such container:path: 050753da4b0a4007d2bd3514a3b56a08235921880a2274dd6fa0ee1ed315ff88:hello.txt
$ # Nope.  Let's take a look at why this is
$ docker container ls -a
CONTAINER ID        IMAGE                        COMMAND                   CREATED              STATUS                          PORTS               NAMES
9e2cb5d38ba0        busybox                      "touch hello.txt"         About a minute ago   Exited (0) About a minute ago                       docker-compose-cp-test_artifact-generator_run_dd548ee686eb
050753da4b0a        busybox                      "sh"                      2 minutes ago        Created                                             docker-compose-cp-test_artifact-generator_1

如您所见, docker-compose ps实际上不了解更新的容器ID。 这是不幸的。 如果我有办法知道run_dd548ee686eb与我执行的docker-compose run有某种关系,这并不会太糟糕,但是我看不出有办法实现。

此解决方法有一个笨拙的解决方法,即将--name到run命令:

$ docker-compose --file docker-compose-minimal.yml run --name blarg artifact-generator touch hello.txt
$ docker cp blarg:hello.txt ./hello-artifact.txt
$ ls 
docker-compose-minimal.yml  hello-artifact.txt

成功! ...有点

这里的问题是,如果我有多个并行运行的构建,则需要麻烦使--name s全局唯一。 否则,最好的情况下会产生嘈杂的冲突,最坏的情况下会导致损坏的结果(没有错误,但提取了错误的文件)。 所以这很笨拙,因为我现在不得不重塑容器ID的生成,而不仅仅是使用Docker已经创建的容器。

至少,我想要某种方式来了解由docker-compose run命令产生的容器的ID。

@ndeloof

依靠$(docker-compose ps -q SERVICE)定位正确的容器,可以将纯docker cli用于此类以容器为中心的操作。

错误,请参阅前面评论中的演示。

我们将在这里拥有多年的新用例。 等等我是说新的反
模式...

2019年12月13日星期五,伊恩(Ian)11:40, notifications @ github.com写道:

@ndeloof https://github.com/ndeloof

依靠$(docker-compose ps -q SERVICE)定位正确的容器
使得可以将简单的docker cli用于此类以容器为中心的
操作。

错误,请参阅前面评论中的演示。

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/docker/compose/issues/5523?email_source=notifications&email_token=AAGRIF2NFPTKY3QKRIXQ5RTQYONHLA5CNFSM4EKAVONKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOMENT
或退订
https://github.com/notifications/unsubscribe-auth/AAGRIF3S4UHF5NG3VKYXJB3QYONHLANCNFSM4EKAVONA

我们可以提到谁去找维护者? 在他们开始与我们交谈之前,这个问题毫无意义。 可能很简单,“由于当前的软件体系结构而无法完成”,无论如何。 但是,从像Docker这样广受欢迎的解决方案中,您并不想看到这种问题保持惰性。

我们的部署使用bazel构建Docker映像,将其上传到我们的Docker Registry,然后使用带有upload节的Terraform docker_container资源将配置文件复制到容器中。 我需要迁移此部署过程以使用docker-compose而不是Terraform。 我很惊讶docker-compose没有为每个容器的配置提供任何功能。

这个问题已经开放了两年。 这就是为什么Kubernetes在流行度上超过Docker的原因吗? Kubernetes提供配置秘密功能。 Docker团队,请至少添加配置功能。

tbf docker-compose无法与k8s完全媲美,因此不建议用于生产环境。 它用于开发和快速测试。 docker swarm是可以与k8s进行比较的东西,尽管它也非常简单,但它确实具有配置和秘密之类的功能。

如果这只是为了发展,那这就是这个问题的更多原因。
应该管用。 糟糕的“反模式”规则甚至不应该是
重要(我之所以说是cr脚的,是因为大量的正常使用很明显
表示它与反模式没有任何相似之处)。

2020年3月3日,星期二,12:56 PM David Milum [email protected]
写道:

tbf docker-compose与k8s不完全一样,因此不建议使用
供生产使用。 它用于开发和快速测试。 码头工人
群体是可以与k8s相比的东西,尽管它也非常
简单来说,它确实具有配置和机密之类的功能。

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/docker/compose/issues/5523?email_source=notifications&email_token=AAGRIFZTKGRWMZZ5H6DG3FDRFUSEJA5CNFSM4EKAVONKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWS016
或退订
https://github.com/notifications/unsubscribe-auth/AAGRIF4NTQQSR2QQWPJT6PLRFUSEJANCNFSM4EKAVONA

另一个“反模式”:

在本地开发期间,我将docker-compose用于容器编排,将k8s用于生产。

根据Docker的建议,我已经实现了wait-for-it.sh脚本以管理服务的启动/关闭顺序。

就目前而言,除非我只想在每个服务中为这个文件装载一个卷,否则这需要在每个服务的Dockerfile包含目录中复制脚本。

相反,我想在顶级目录中维护wait-for-it脚本的单个副本,然后在本地运行时将docker-compose复制到每个容器中,否则这些问题可以在k8s中进行管理,这意味着我不希望这些担忧污染我的服务的Dockerfile s。

正如爱默生曾经写道:“愚蠢的一致性是小政治家,小政治家,哲学家和神圣主义者所崇拜的小头脑的妖怪。”

也许是时候听您的用户了...

@Phylodome您不能使用容器运行状况检查和docker-compose depends_on吗? 这就是我确保健康的容器启动依赖关系的方式。

我的理解是wait-for-it.sh确实是一个黑客,因为您的服务本身应该能够适应来来往往的依赖关系。 启动只是一个例子。

@ianfixes “您的服务”是指

“您的服务”是指docker-compose服务本身,还是“我们的”服务,例如我们使用docker-compose编写的服务?

您作为开发人员构建的服务应具有弹性。 这是根据这些文档: https :

等待数据库准备就绪的问题实际上只是分布式系统更大问题的一个子集。 在生产中,您的数据库可能随时不可用或移动主机。 您的应用程序需要能够应对这些类型的故障。

要解决此问题,请设计您的应用程序以尝试在失败后重新建立与数据库的连接。 如果应用程序重试连接,则它最终可以连接到数据库。

最好的解决方案是在启动时以及由于任何原因断开连接时都在应用程序代码中执行此检查。 但是,如果不需要此级别的弹性,则可以使用包装器脚本解决此问题:

并继续提到各种等待脚本。

可以做很多事情。 但是因为这只是为了本地开发,并且因为我还有其他策略来处理k8s中的生产服务检查,所以我宁愿使用最简单且干扰最小的本地实现方式,而不希望那些不了解我为什么要这样做的人的通用建议d愿意这样做(例如,为了通过Webpack的dev服务器执行UI dev而出现卷安装问题)。

无论如何,这只是功能的一长串用例中的另一个,应由用户自行决定。

我听到对我发怒,并且我明白为什么听到不请自来的“建议”会令人沮丧。 但是我什至不知道该如何道歉。 我引用了您自己称为“ Docker自己的建议”的URL中的文本,该文本表示_explicitly_等待脚本是“解决问题”的一种方式。 无论如何,很抱歉。

您没有听到愤怒。 您听到的是某个人的恼怒音调,他们在搜寻应该是一个相当明显的功能时偶然发现了一百条评论,其中一组维护者不断光顾并拒绝社区对一项完全有效功能的要求。

我没有在这里分享我的经验b / c我想道歉。 我分享它只是为了添加一长串证据,即Docker用户在使用compose时希望获得更大的灵活性。

当然,像任何工具一样,这种灵活性与滥用的可能性同时存在。 但是,当您的用户必须找到解决方法来解决其特定用例时,就存在相同的潜力,即使不是更糟的潜力,也可以通过添加此功能来更简单地解决。

此外,对您的用户造成歉意的外观不好。

我既不是该项目的维护者,也不是该项目的贡献者,对于由此给您带来的任何困惑,我深表歉意。 听起来我以为我能提供的一点帮助都是不必要和无助的,我很抱歉浪费您的时间。

我需要Go容器的此功能,该容器是我的分布式应用程序的一部分。 由于.env文件需要包含在Go应用程序的根目录中,因此我需要为其创建一个单独的.env ...如果有此功能,我可以建立我的顶层.env文件,并在构建时将其复制到Go容器中。 这意味着我需要跟踪的东西更少了...

我的解决方法可能是通过Go容器的Dockerfile创建此文件,或者只是为该容器制作.env文件。 但是,无论何时,只要我添加一个新的环境变量,我都可能需要在两个地方进行更新。 这里的用例很好。 或者我可以只使用shell脚本为我cp文件...

+1用于复制功能

我们已经在Kubernetes中使用边车实现了这一点,并且有很多用例。 这不是反模式,只是保持docker-compose的功能之一。

也许我错过了一些东西,但是现在当我们在构建应用程序5分钟时,构建文件夹一直处于“不断变化中”状态,并且由于不一致,应用程序将无法启动。
我更喜欢将一个构建文件夹复制到一个容器中,因此当需要启动该容器时,它将接管内部的一个。 这样,当停止/启动容器时,该应用程序仅离线大约一秒钟。

docker已经支持它时,这如何成为反模式? 将docker-compose作为docker的可用性来遵循是很有意义的-不这样做本身就是一种反模式。

这样做的问题是它的视力难以置信(因此称为“反模式”),因为它将迫使您每次重新创建容器时都要重复操作。 更不用说它的伸缩性很差的事实(如果您有10个容器该怎么办?20到100个?)

我认为这取决于开发人员。 仅复制单个本地配置文件就不会产生太大的开销。 不要怪这把刀。


PS我的用例; 我想在没有Dockerfiles的项目中向Nginx容器添加配置。

谁知道了。
我需要建立一个新项目并寻找新的
工具,Lando比这要好得多,这太疯狂了。 希望我用过
早点
它更快,更容易理解,开箱即用的支持和
没有居高临下的(例如)维护者/贡献者。

@ chris-crone关于您的评论...

对于配置文件或引导数据,有Docker Configs。 这些工作与机密类似,但是可以安装在任何地方。 Swarm和Kubernetes支持这些,但docker-compose不支持。 我相信我们应该增加对这些的支持,这将有助于解决本期中列出的一些用例。

docker-compose是否有兴趣通过swarm config实现对奇偶校验的配置支持?

如果有一张票(或者如果我也需要做一张票),我想订阅该票,并取消订阅此垃圾焚烧。 就我个人而言,我将关闭它并链接到该对象,但这仅是我自己。

@harpratap是正确的,但是缺点是/ folder_in_container不能存在或必须为空,否则它将被覆盖。 如果您将bash脚本作为入口点,则可以在/ some_empty_location创建卷后,通过将文件符号链接到最初预期的目录中来规避此问题

+1具有COPY功能。 我们的用例是快速建立本地开发环境并复制开发设置的配置。

究竟。 我们并非都以相同的方式扩展。 我的公司使用SALT为各种应用程序构建所需的.conf文件。 一种构建-具有基础-然后docker-组成以根据其唯一部分(MAC地址,IP,端口,许可证,模块等)创建各个实例。它可以通过命令行完成-但要容易得多,省事得多docker-compose容易出错。

我有一个用例。 我们有一个测试构建,要求设置ssl。 证书是由docker-compose中的服务生成的...我然后将这些证书添加到客户端容器中...如果我挂载,我会丢失现有证书,并且由于它们不存在而无法将其放入docker构建中还不存在。

因此,我必须运行2 docker-compose-1启动服务以创建证书,然后运行另一个以构建服务并运行测试。 乱。

我在这里看到了很多问题,用户为该功能提出了很多用例,但遭到维护者认为是反模式,或者人们不会使用它或其他故事,因此遭到了拒绝。 。

尽管对于一个人来说,这似乎是一种反模式,但我敢肯定,要求该功能的1000人也需要听取他们的意见。 如果需要一些帮助来开发该功能,我认为很多人都可以伸出援手。

我的用例:除了配置外,我还需要在5个Rails应用程序容器(Debian)中安装一些库(RPM)。 不同的Ruby / Rails版本不同,因此不能使用相同的基本映像,因此我应该能够将文件存储在一个位置,并在构建时将它们复制到容器中,因为我不想下载1.5GB的数据在建造时。

@gauravmanchanda

我的用例:除了配置外,我还需要在5个Rails应用程序容器(Debian)中安装一些库(RPM)。 不同的Ruby / Rails版本不同,因此不能使用相同的基本映像,因此我应该能够将文件存储在一个位置,并在构建时将它们复制到容器中,因为我不想下载1.5GB的数据在建造时。

您是否为此考虑过多阶段构建? 我认为这将是一个更强大的解决方案。

多阶段构建允许您将同一Dockerfile用于多个映像。 这使您可以分解它们,并且仅在每个图像中包含所需的位。

一个很好的例子就是我们用来构建Docker Compose的例子。 它使用Debian或Alpine构建,但允许我们分解通用代码。

在我们的设置中,我们使用docker-compose增强了大约十二个模拟器。 模拟器是相同的,但是每个目标的一个初始化文件都不同,并且该文件在启动时使用(在服务器启动并运行时将其删除)。 您是否真的建议我们仅由于一个文件不同而创建大约十二张几乎相同的图像? 海事组织这没有道理。

对于docker,可以使用--copy-service标志来实现。 我们可以与docker-compose搭配使用吗?

@megaeater

我们使用docker-compose增强了大约十二个模拟器。 模拟器是相同的,但是每个目标的一个初始化文件都不同,并且该文件在启动时使用(在服务器启动并运行时将其删除)。

这是一个有趣的用例; 一些问题:这些模拟器(或其一部分)是否曾经在生产环境中运行过(即:不在开发人员的机器或CI上)? 如果代码是开放的(或类似的系统),您可以将我链接到该代码,以便我看看吗?

知道为什么要复制这些文件而不是绑定安装或卷也将很有趣。

您是否真的建议我们仅由于一个文件不同而创建大约十二张几乎相同的图像? 海事组织这没有道理。

正是由于这个原因,图像基于图层:除了包含不同文件的图层之外,所有图像都将引用相同的图层。

诸如在容器上创建副本之类的问题的问题在于,这会使采用相同的代码并在生产环境中运行它变得困难(即:需要重写主要逻辑),因为该模式在精心设计的环境中将是脆弱的或不可能的。

这并不是说我们永远不应该在Compose中实现这样的事情。 而是当更改意味着用户将无法重用在生产环境中本地运行的某些功能时,我们希望暂停一下,看看是否有更强大的方法可以实现同一目标。

谢谢你的评论@ chris-crone

我们不在生产环境中运行docker,仅用于开发目的。 使用卷的问题(如果我理解正确的话)是模拟器(第三方)具有此启动脚本,该脚本在启动时会删除文件。 如果删除失败,脚本将停止执行,因此我们需要将其挂载为rw。 而且,如果允许删除文件,我们将需要一种机制来创建一个临时目录来提供这些文件,以免原始文件被删除。 因此,我们将需要某种无关的脚本来增加docker-compose之上的组成。

@ chris-crone谢谢您的链接。 我看一下它是否对我们有用👍

嘿@ chris-crone我确实尝试使用多阶段构建,它确实帮助我们将库/配置仅保留在1个位置并在周围复制,但是现在存在.dockerignore问题,无论在哪里我放

当我仅将Docker与新的DOCKER_BUILDKIT选项一起使用时,它可以工作,但在使用docker-compose尝试了COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose build ,它不起作用,但仍然无法工作。 有任何想法吗?

我想知道,当我偶然发现此问题https://github.com/docker/compose/issues/6022时,是否有一个选项可以指定在哪里查找.dockerignore内容,已关闭,coz 1提供者认为这没有用。

如果我在这里老实说,这真令人沮丧!!

这对于MacOS至关重要,因为使开发周期尽可能接近生产至关重要。 显然是为了正确的持续交付做法。 例如,构建容器,然后将当前正在使用的软件的新版本绑定安装到容器中,以节省构建周期。 不幸的是,绑定安装非常昂贵,要慢3到5倍。

例如,在容器中,我的应用程序的tomcat启动时间约为3s。 添加〜/ .bash_history的绑定挂载,它是4s。 添加我的应用程序的绑定安装,通常大约需要18-20秒。 在Linux中,绑定安装性能类似于本地文件系统,但在MacOS中则不同。 将其扩展到每天100次,这很重要。

这还不包括首次访问该应用程序时持续的缓慢性; 直到代码文件被缓存。 对我来说,这意味着3分钟,包括通过连接到整体式oracle db的Internet延迟将一个小短语更改为其他内容,然后查看它是否仍然正常。 该死的covid-19,哈哈。

理想情况下,我希望能够再次运行docker-compose并在正在运行的容器中“更新”我的应用程序,并要求tomcat重新加载。 我可以使用tomcat管理器上传更改,但是我们还有一个后端应用程序,该应用程序不使用任何托管容器,因此我们不得不为此使用其他解决方案。

如果docker-compose也面向开发,而不仅仅是生产部署,那将是很好的。

该用例与讨论有关: https :

@ chris-crone

@gauravmanchanda

我的用例:除了配置外,我还需要在5个Rails应用程序容器(Debian)中安装一些库(RPM)。 不同的Ruby / Rails版本不同,因此不能使用相同的基本映像,因此我应该能够将文件存储在一个位置,并在构建时将它们复制到容器中,因为我不想下载1.5GB的数据在建造时。

您是否为此考虑过多阶段构建? 我认为这将是一个更强大的解决方案。

多阶段构建允许您将同一Dockerfile用于多个映像。 这使您可以分解它们,并且仅在每个图像中包含所需的位。

一个很好的例子就是我们用来构建Docker Compose的例子。 它使用Debian或Alpine构建,但允许我们分解通用代码。

多阶段构建很酷,但是它们会遇到自己的问题,因为您必须在同一上下文中运行所有阶段,但这并非总是可能的。 此外,据我所知,你不能轻易使用COPY --from与另一个Dockerfile定义,并内置图像docker-compose build (我假设你可以通过建立和手动标记他们这样做)。

COPY本身非常有限,因为您只能从构建上下文中导入。 docker cp可以从任何地方复制到任何地方,除了它不能在图像和容器之间复制(类似于COPY --from )。

我自己的用例有点不同(除了复制只读配置文件外,在部署到另一台计算机时,本地卷挂载不是最好的主意),我会说我现在正在做的是一种反模式... 。 我可能会在构建时生成几个不同的图像,这些图像会生成经过编译和精简的JS + HTML +资产捆绑包(请考虑使用小型角度应用程序),以及一个为所有图像提供服务的单个nginx服务器(由于插件而从自定义图像构建的nb)。

当前,我要做的是在启动时从“构建”映像中复制“部署”包。 理想情况下,这应该在容器创建或构建上完成,但后者需要在“ moded nginx”之上创建另一个图像。

对以下项目布局进行映像(子项目可能位于单独的存储库中,并且彼此之间不了解):

app1/
  src/
    ...
  Dockerfile
app2/
  src/
    ...
  Dockerfile
app3/
  src/
    ...
  Dockerfile
nginx/
  ...
  Dockerfile
docker-compose.yml

每个文件app{1,2,3}/Dockerfile包含一个目标/阶段build ,可将应用程序构建为/usr/src/app/distnginx/Dockerfile仅具有一个阶段,并构建类似于nginx/nginx的映像,但具有所有必需的插件(无配置)。

docker-compose.yml:

version: '3.8'
services:
  app1-build:
    build:
      context: app1/
      target: build
    image: app1-build
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        rm -vfr /dist-volume/app1 \
        && cp -vr /usr/src/app/dist /dist-volume/app1 \
        && echo "Publishing successful"
    volumes:
      - 'dist:/dist-volume'

  app2-build:
    build:
      context: app2/
      target: build
    image: app2-build
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        rm -vfr /dist-volume/app3 \
        && cp -vr /usr/src/app/dist /dist-volume/app3 \
        && echo "Publishing successful"
    volumes:
      - 'dist:/dist-volume'

  #... same thing for app3-build

  nginx:
    build:
      context: nginx/
    image: my-nginx
    volumes:
      - 'dist:/var/www'
      - # ... (config files etc)

volumes:
  dist:

现在,这显然是不理想的,每个应用程序构建映像都不必要地运行并快速完成,已部署的映像驻留在共享卷上(我假设这会对性能产生负面影响,但我无法对其进行验证)。 如果copycopy_from是docker-compose选项,则可以这样写:

version: '3.8'
services:
  # assuming the images have default entrypoint and cmd combination that immediately returns with success.
  app1-build:
    build:
      context: app1/
      target: build
    image: app1-build

  #... same thing for app2-build app3-build

  nginx:
    build:
      context: nginx/
    image: my-nginx
    copy:
      - from: app1-build  # as image or service, both have their pros and cons, service would mean an image associated with this service
         source: /usr/src/app/dist
         destination: /var/www/app1
      - from: app2-build
         source: /usr/src/app/dist
         destination: /var/www/app2
      - from: app3-build
         source: /usr/src/app/dist
         destination: /var/www/app3
    volumes:
      - # ... (config files etc)

我的用例不在构建步骤或启动步骤中。 我正在获取在容器或服务的所有容器内生成的文件,这些容器在远程Docker Engine上执行。 到目前为止,我发现自己正在执行类似docker-compose ps -qa <service> | xargs -i docker cp {}:<there> <here> 。 我只希望我可以在脚本中坚持使用docker-compose。

@ chris-crone

知道为什么要复制这些文件而不是绑定安装或卷也将很有趣。

你喜欢自我鞭打吗? 如果是这样,我建议在MacOS上使用绑定安装来运行应用程序。 the有关详细信息,请参见我以前的文章。

这并不是说我们永远不应该在Compose中实现这样的事情。 而是当更改意味着用户将无法重用在生产环境中本地运行的某些功能时,我们希望暂停一下,看看是否有更强大的方法可以实现同一目标。

@ chris-crone我认为这是一个很好的想法,因为人们经常会为docker实现反模式,例如不以临时方式管理配置和数据。

我想知道我们是否可以使Docker和Apple一起解决绑定安装的性能问题。 至少对我而言,我不再需要docker compose cp选项,因为我将使用绑定挂载进行开发。 现在,尽管使用绑定安装太痛苦了。 我可能会切换到装有Linux的虚拟机,导致Mac仅有字节。

@megaeater

我们不在生产环境中运行docker,仅用于开发目的。 使用卷的问题(如果我理解正确的话)是模拟器(第三方)具有此启动脚本,该脚本在启动时会删除文件。 如果删除失败,脚本将停止执行,因此我们需要将其挂载为rw。 而且,如果允许删除文件,我们将需要一种机制来创建一个临时目录来提供这些文件,以免原始文件被删除。 因此,我们将需要某种无关的脚本来增加docker-compose之上的组成。

嗯。如果您可以与模拟器供应商合作,我认为这是解决此问题的最佳方法。 您也许可以使用模拟器的入口点脚本来解决此问题,该脚本可以根据需要移动文件; 当然,这将是一团糟。

@gauravmanchanda

它确实帮助我们将库/配置仅保留在1个位置并进行复制,但是现在存在.dockerignore被忽略的问题,无论我将其放置在何处。
当我仅将Docker与新的DOCKER_BUILDKIT选项一起使用时,它可以工作,但在使用docker-compose尝试了COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose build ,它不起作用,但仍然无法工作。 有任何想法吗?

高兴的多阶段构建帮助了! 您正在使用哪个版本的Docker和docker-compose? 我会尝试最新的,看看问题是否仍然存在。 它应该尊重.dockerignore文件。

@Marandil ,听起来好像docker build没有处理项目结构(即目录结构),这是问题所在。 您可能可以使用docker buildx bake (https://github.com/docker/buildx)之类的方法来解决此用例。 注意buildx正在开发中,因此还不是非常稳定,但是它旨在解决您遇到的一些问题。

@itscaro ,谢谢您的投入! 我们内部在容器中生成事物的操作是使用docker buildFROM scratch图像输出结果。 这仅在需要单个容器的输出的情况下有效。

@TrentonAdams我们一直在努力改善Docker Desktop的文件系统性能,但这很棘手。 潜在的问题是穿越虚拟机边界。 文件共享位最近已被重写(可以使用首选项中的“使用gRPC FUSE进行文件共享”切换来启用新的体验),这应该可以解决人们已经看到的一些CPU使用率过高的问题。 我们这里这里都有一些有关性能调优的文档。

@ chris-crone

@Marandil ,听起来好像docker build没有处理您的项目结构(即目录结构),这就是问题所在。 您可能可以使用docker buildx bake (https://github.com/docker/buildx)之类的方法来解决此用例。 注意buildx正在开发中,因此还不是非常稳定,但是它旨在解决您遇到的一些问题。

谢谢,我将研究docker buildx bake 。 它看起来很有希望,但是我找不到很好的参考资料或文档,而且docs.docker.com上的页面也很裸露(请参阅https://docs.docker.com/engine/reference/commandline/buildx_bake /)。 到目前为止,我发现https://twitter.com/tonistiigi/status/1290379204194758657引用了几个示例(https://github.com/tonistiigi/fsutil/blob/master/docker-bake.hcl,https:// github .com / tonistiigi / binfmt / blob / master / docker-bake.hcl),这可能是一个很好的起点,但很难成为一个很好的参考。

@TrentonAdams我们一直在努力改善Docker Desktop的文件系统性能,但这很棘手。 潜在的问题是穿越虚拟机边界。 文件共享位最近已被重写(可以使用首选项中的“使用gRPC FUSE进行文件共享”切换来启用新的体验),这应该可以解决人们已经看到的一些CPU使用率过高的问题。 我们这里和这里都有一些有关性能调优的文档。

@ chris-crone地狱是的,非常感谢! 新选项使性能提高了3-4s,使用“缓存”可以为我提供与在容器外部运行相同的性能,因此对我来说这是巨大的。 我看到应用程序的启动时间可低至2800毫秒,因此不再是11-18秒。 好极了! 除了缓存之外,我不需要任何东西,因为无论如何,我只是每次都在重新创建容器。

@ chris-crone我应该在某个地方发布性能资料以帮助MacOS进行性能调整和反馈吗? 我想知道为什么不使用cached时带绑定安装的新启动容器会变慢。 在启动时来回检查每个文件是否同步是否一定有些奇怪的事情,即使它们是全新的也是如此?

用例:我运行一个容器,它修改了一个文件(具体地说,Keycloak根据环境变量等修改了它的配置文件)。 我想要在本地磁盘上复制该文件,以便可以检查该修改的结果,并在修改容器脚本时跟踪我的进度。 当前,我每次都需要查找新的容器ID,以便可以使用docker cp

用例:
在docker中开发。
我需要向后传播我的锁定文件到主机,否则当容器安装项目文件夹时它会被覆盖。

用例:我需要复制一个包含密钥的文件。 在容器内运行的应用程序将该文件读取到内存中,并将其从磁盘中删除。

用例:我在docker容器中运行c ++单元测试。 我只想在每次运行时将代码复制到现有图像上。

1)使用单独的dockerfile COPY意味着代码被写入到新的不必要的映像中,我需要删除该映像以确保下一次运行使用最新代码创建新映像。

2)使用docker-compose volumes yaml config进行此操作意味着Docker将源代码打包root:root (完全杀死了我的IDE,直到进行编辑为止!)

@ shin-我是否通过在容器中运行单元测试来遵循反模式? 您要解决的非反模式方式是什么?

....我坚持选择1,因为这是最少的痛苦。 但我看到docker-compose支持复制配置是如此强大的增强功能! 至少对于这个工作流程!

@soulseekah是否针对该用例使用了更好的秘密

我找到了一种适合我的解决方法:

  1. 用以下命令创建Dockerfile
    COPY a_filename .
  2. 使用Dockerfile构建映像
    docker build -t myproject:1.0 .
  3. 编辑docker-compose以使用您刚刚构建的图像
version: "3.7"
services:
  app:
    image: myproject:1.0
    ports:
      - 3000:3000
    networks:
       - mynetwork
       - internal
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: not_so_secret_password # don't do this 
      # https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/
      MYSQL_DB: appdb
    deploy:
      resources:
        limits:
          cpus: '0.75'
          memory: 100M

这不是一个完美的解决方法,但是它在我的用例中有效。

@soulseekah是否针对该用例使用了更好的秘密

不幸的是,这最后一次需要蜂拥而至:(

@soulseekah是否针对该用例使用了更好的秘密

不幸的是,这最后一次需要蜂拥而至:(

@soulseekah也许使用我使用的解决方法(在您之上)?

@zoombinis注释中指出了@ChristophorusReyhan的解决方法:

使用单独的dockerfile COPY进行此操作意味着代码被写入到新的不必要的映像中,并且我需要删除该映像以确保下一次运行使用最新代码创建新映像。

当解决方案有效时,可能会导致不必要的维护。 例如,要清理不需要的图像_,同时还要保留您关心的任何图像_:

docker-compose up && docker-compose down --rmi local

但是请确保您关心的所有图像都具有自定义标签,并且测试/虚拟图像没有

此页面是否有帮助?
0 / 5 - 0 等级