Compose: 将`copy`添加到yaml配置

创建于 2015-07-07  ·  146评论  ·  资料来源: docker/compose

我想使用相同的映像但使用不同的配置文件来部署不同的服务。
目前实现我可以

  • 构建尽可能多的图像,这些图像继承自同一图像,并且每个图像中都包含不同的COPY
  • 挂载单个文件卷

第一个解决方案不可行,第二个解决方案是过大的。 我只想复制一个文件,而不要保持同步

建议的配置:

myservice:
    image: foo/bar
    copy:
        - src:dest
areconfig

最有用的评论

复制是一项操作,不是服务配置的一部分,因此它不属于撰写文件。

如果只想复制配置文件怎么办? (到码头工人群,因此volume_from不起作用)

我有完全相同的情况,想要复制自定义mysql,nginx,haproxy等配置文件,我们在生产环境中使用集群,而不是仅使用一个copy命令将配置从本地复制到远程

我每次都必须使用映像,构建,拉动,而无需任何操作,只需复制命令即可节省大量的部署和开发时间

所有146条评论

copy的语义是什么? 我们是否使用docker cp从运行docker-compose的主机复制文件到新运行的容器中?

AFAIK目前没有这样做的方法:

看到:

``#!bash
$ docker cp -h

用法:docker cp [选项]容器:PATH HOSTDIR |-

将文件/文件夹从容器上的PATH复制到主机上的HOSTDIR
运行命令。 使用“-”将数据作为tar文件写入STDOUT。

--help = false打印用法
```

复制在这里的含义是什么? 我们是否使用docker cp将文件从运行docker-compose的主机复制到新运行的容器中?

AFAIK目前没有这样做的方法:

我看到docker cp命令无法执行此操作。 但是仍然可以通过在主机端访问容器数据来实现(我认为这很丑陋)

http://stackoverflow.com/a/24805696/210090

是的,我根本不会提倡我们这样做。 这将打破关于Docker的许多东西和假设。 这也高度依赖于所使用的基础存储驱动程序。 Docker不可知。 我认为我们_应该_为您的问题提供另一种解决方案:)

既然docker-1.8添加了对通过docker cp复制到容器中的支持,而swarm-0.4.0-rc2添加了对docker cp ,那么重新撰写此级别的问题将是很棒的。 这是用例(它反映了我们现在在_almost_生产中实际执行的操作):

一个docker-compose.yml文件,该文件通过CI构建的图像标签提及了许多容器(即,我们在生产中不使用build: ;也许我们现在可以使用,但是在过去的发行版中,它与swarm配合不好)所有这些都需要,例如,映射的静态hadoop配置文件与部署环境完全匹配。 当前,必须手动将docker-compose.yml所在的目录同步到群集中_each_目标docker-machine上的确切路径。 然后添加一堆volume:行。

支持docker cp可以删除我们系统部署方法中的自定义配置文件同步,并可以更好地控制何时注入配置更改(因为任何更改volume:行中提到的文件的人都会受到影响所有先前部署的容器(以及内部实现何时重新读取所述配置,可能仅在下一个容器重新启动时,可能在容器内的各种工具启动时;这可能是意外的)和将来的(预期的)。

OTOH,(如上所述),也许我们应该使用build: 。 缺点是我们需要为每种部署容器类型编写一个额外的Dockerfile。 一个用于CI构建的映像,另一个用于静态配置文件注入器。 copy:通过最近的变化,以支持撰写docker cp将整齐地使我们避免这一切的重复。

似乎仍然使用卷是一种更好的方法。 它不必是主机卷,它应该与数据卷容器一起使用。

Bedies docker-machine仍然有docker-machine scp ,您可以通过准备机器来完成; 然后您就可以按照正常方式dockerdocker-compose进行主机卷

“使用卷似乎仍然是一种更好的方法。它不一定是主机卷,它应该与数据卷容器一起工作。”
当目标是一群时,我看不到那是最好的。 AFAICS,无法表达在每个可能的群集节点上都应存在一个数据卷容器的方法。

是否不能像其他任何容器ala调度策略一样,通过群集本身在节点上部署数据卷容器?

“无论如何,您可以通过准备机器来完成docker-machine的docker-machine scp操作;然后您可以使用docker或docker-compose的常规方式进行主机卷”
我目前正在这样做。 真痛苦管理部署的人员忘记移动配置文件。 如果在docker-compose yml中受支持,则在没有手动步骤的情况下重新创建容器时就会发生。

“您是否不能像其他任何容器ala调度策略一样,通过群集本身在非常节点上部署数据卷容器?”
也许可以,但是我承认我不知道如何扩展。

“您是否不能像其他任何容器ala调度策略一样,通过群集本身在非常节点上部署数据卷容器?”
嗯,如果我知道我的集群是10个节点的大小; 我是否可以通过在给定的Docker引擎节点上不允许复制的策略将数据卷容器缩放为10号大小? 问题(除非我错过了一些事情)是,例如,需要引用该数据量的容器无法从具有匹配索引的容器中进行--volume。 伙计们,我已经研究这个问题两个月了。 我能做的最好的就是创建一个使用docker-machine scp的脚本。 但这是在编辑配置文件之后和docker-compose up之前的手动步骤。 它还要求人们可以在docker-compose.yml的根目录下,在群的目标计算机上写出确切的路径(即,闻起来像是一种主要的hack)。

也许我在工厂的努力可以帮助自动完成将docker机器和集群clsuter纺成一团的过程,并让其中的“正确”数据可供使用? (_尽管它仍处于早期开发阶段,但我正在使用它将docker-machinedocker-compose到一个setp_0中。

copy是一个操作,不是服务配置的一部分,因此它不属于撰写文件。

Docker 1.9正在添加新的卷api,并且已经安装了卷驱动程序。 卷确实是支持此功能的正确方法。 不尝试复制文件。

谢谢你的建议! 但是我不认为这真的适合现在的compose设计。

复制是一项操作,不是服务配置的一部分,因此它不属于撰写文件。

如果只想复制配置文件怎么办? (到码头工人群,因此volume_from不起作用)

我有完全相同的情况,想要复制自定义mysql,nginx,haproxy等配置文件,我们在生产环境中使用集群,而不是仅使用一个copy命令将配置从本地复制到远程

我每次都必须使用映像,构建,拉动,而无需任何操作,只需复制命令即可节省大量的部署和开发时间

让我感到非常惊讶的是,越来越多的人对此不存在编写脚本的问题。 我在想码头工人错了吗? 我认为我现在的解决方案是使用ansible将配置文件复制到主机,然后从主机进行卷挂载到需要它的容器

碰到同样的问题。 我正在为N个不同的服务重用Dockerfile,并且我不想使用其自己的COPY命令创建N个不同的Dockerfile或仅为此创建一个卷。

顺便说一句,我目前正在通过运行数十行sed命令来解决该问题-http: //unix.stackexchange.com/questions/112023/how-can-i-replace-a-string-in-a-files

也许不是最佳解决方案,但考虑到docker-compose不支持复制文件,因此可以工作。

顺便说一下,当然可以进行挂载和复制,但是它与自动化docker-compose提供的功能相违背-如果我更愿意手动完成所有操作,我不会使用docker-compose,不是吗?

我对Docker的研究越深入,似乎该工具中的许多工具对于“ hello world” /“看看我能以多快的速度使用\ shell \命令\ like \ this \”来启动这个很酷的东西就好了。单机类型用例(包括docker-compose)。 如果不止于此,事情将变得相当复杂,并且IMO会崩溃,这是传统配置工具可以使用并节省适当使用时间的地方。

我发现使用Ansible以幂等的方式设置计算机非常容易,因为我有特定于计算机的卷,文件和模板化配置文件才能启动docker映像。 然后最后,我可以使用Ansible调用docker-compse甚至使用Ansible docker模块,其语法与docker compose几乎完全相同,并具有一些不错的附加功能。

归根结底,上述方法允许对所有内容进行脚本化,幂等,并且最重要的是将其检入源代码管理中。

@dnephin上面的某些人建议将CP的用例作为配置的一部分,是否有必要重新考虑一下CP仅用于操作而不是配置的假设。

一个简单的示例是创建一个容器,在正确的位置复制配置,在复制完配置后启动容器。

这允许创建不嵌入实际配置而仅在容器启动时部署配置的映像。

绝对会非常有帮助。 我现在正在将postgres图片作为数据库后端使用,我不想重建它,只是更新/docker-entrypoint-initdb.d文件夹中的脚本。

你们为什么不重新打开此问题,直到实现该功能或找到人们喜欢的可行解决方案,因为这里没有人喜欢建议的选项?

正如@ctindel所提到的,此问题应重新打开。

+1已重新打开问题

+1也可以打开。

+1重新打开。

+1重新打开。

+1重新打开。

+1重新打开。

+1重新打开。

+1重新打开。

只读卷有什么问题?

myservice:
    image: foo/bar
    volume:
        - src:dest:ro

@michaelarnauts看到这个

👍重新开放

+1重新打开。

+1重新打开。

+1重新开启

+1重新开启

+1重新开启

+1重新开启

+1重新开启

+1重新开启

这是允许在Compose中进行复制的理由。

我有一个可以在众多容器上运行的应用程序。 为了争辩,让我们规定它们都运行Apache。 它们都有指向诸如“ / var / www / partX”之类的DocumentRoot定义。 Dockerfile对Apache配置的内容一无所知,并且Compose定义了/ var / www / partX的卷参考。 这对开发非常有用,因为我可以在不修改容器内容的情况下调试和调整代码。

碰到的是我想部署的时间。 Docker的主要吸引力之一是,我可以部署一个自己的容器。 为了将所有内容保存在容器中,我必须复制文件,这意味着我必须将用于开发的Dockerfile和Compose定义分开。 在大型项目中,这意味着我必须维护两组定义文件,这会引入更多的错误可能性。

我的首选是维护一组Dockerfile,并在Compose文件上进行编排。 我将在Compose中定义是将/ var / www / partX设置为共享卷,还是将文件复制到容器中。

使用共享卷进行部署似乎像蠕虫一样。 如果要更新生产中依赖于共享卷的现有版本,则在没有设置维护窗口或提出用于对共享卷进行版本控制的方案之前,无法更新该共享卷。 我正在将容器与外部文件紧密耦合,如果要介绍这种类型的复杂性,则会否定使用Docker的一些好处。

似乎我可以脚本化对Dockerfile定义的更改以有条件地复制文件,但是似乎更多的“逻辑”确实可以处理Docker Universe中的所有Docker逻辑,而Compose似乎是一个合乎逻辑的地方。

+1重新打开。

+1。 将配置文件复制到docker-compose.yml文件而不是Dockerfile将非常有帮助。

+1。 刚遇到它试图提供服务的配置文件。 只读卷似乎是一个选择,但宁愿将其复制。

简单地安装一个卷就可以达到目的:

version: '2'
services:
  foobar:
    image: 'postgres:9.6-alpine'
    volumes:
      - './docker/schemas/foobar:/docker-entrypoint-initdb.d'

@raszi-是的,安装的配置是我们现在要走的方向。 我最喜欢Docker的一件事是一个独立容器的概念,我可以在该容器上运行集成测试,而无需考虑外部依赖项(例如链接配置)。 如果我要进行蓝色/绿色或A / B部署,并且不同版本的容器使用的配置有所不同,则情况可能会变得有些脆弱。 我可以通过在每个环境的共享卷中执行诸如配置文件版本控制之类的事情来解决此问题,但这似乎比它可能更复杂或更脆弱。

“ Docker容器将一个软件包装在一个完整的文件系统中,该文件系统包含运行所需的一切:代码,运行时,系统工具,系统库–可以安装在服务器上的任何东西。这保证了该软件始终可以运行相同的功能,无论的环境。” 对我而言,理想情况下将包括配置。 Compose有点像“构建/编译并运行”,我想我们当中有些人希望Compose能够进行“构建/编译,链接并运行”。 它不是今天的工作方式,我可以理解缺乏走那条路线的热情,但是,嘿,这是一个论坛,问这个问题并不无害;)

我同意,拥有此功能会很棒。 我刚刚发布了自己的解决方案来帮助他人。

+1重新打开。

+1

+1用于重新打开或使用其他没有卷的解决方案。

当前在运行容器的主应用程序之前,先在docker-entrypoint.sh中使用docker-compose.yml和j2中的Environment变量将它们解析为配置文件。 对我有用,尽管它是自定义图像,不能与已经可用的完整图像一起使用。

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1重新开启

为了增加每个容器具有不同的Yaml文件而不是基于环境变量进行配置的可能性

+1非常需要的功能

+1,很高兴拥有功能!

+1

+1

+1

+1

+1重新开启。 已收藏

+1这是非常需要的功能。

如果有某种方法可以将共享卷标记为一个层,则该卷仍为RO,但写入操作应用于顶部的层,而没有copy指令,我会过得很愉快。 例如,我想共享一个提取的构建工件,但是该服务将写入该目录(日志或PID文件等)。

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1重新打开,因为这将是一个非常有用的功能

也许https://github.com/jwilder/dockerize的模板功能可以帮助某些人

+1

+1

+1

+1

+1

+1重新打开问题

+1

使用Docker机密,在此示例中,机密与Nginx映像一起使用以复制服务器证书和配置文件
https://docs.docker.com/engine/swarm/secrets/#intermediate -example-use-secrets-with-a-nginx-service

那是个很好的观点。 坦白地说,由于我们已经有了秘密,因此我们应该拥有副本,因为从某种意义上说,秘密只是要复制的特定类型的文件。 就是说,它是经过更仔细地配置的,我们不需要配置文件。

它击败了主机为您要包括的每个配置文件安装卷。

如前所述:

...
数量:
-./nginx/default.conf:/etc/nginx/conf.d/default。 conf:ro
-./nginx/nginx.conf:/etc/nginx/nginx。 conf:ro
...

复制的原因更好:a)在主机实际上是独立机器的集群环境中,您不必在每台机器的相同位置上拥有完全相同的文件。 b)复制也可以限制为文件夹位于其中,而主机挂载则需要绝对路径。 c)我认为docker的目的是尽量减少所包含的应用程序侵入主机的位置。 即使将主机挂载配置为只读,它也会在主机上负责拥有保留文件。 我们不必使用主机安装来解决这个简单的问题。

我认为复制的建模方式类似于docker build流程,其中Dockerfile通常与所有需要发送到构建上下文的文件一起存储在git存储库中。 Dockerfile不允许发送目录结构之外的任何内容,即使其符号正确链接也是如此。 我们可能会在compose中遇到类似的情况,其中src仅限于docker-compose.yml的目录(及以下目录)。 基本上,工作流程是, docker-compose创建容器,然后对于每个src:dst对,在当前目录下找到src ,并将其复制到未启动的容器中,然后启动容器。

当前,可以通过添加额外的Dockerfiles并将conf文件构建到修改后的图像中来避免主机挂载,但是对我来说这似乎太过分了,因为它涉及到重新标记新图像或强制用户使用docker-compose build属性而不是更可取的(IMO) image属性。 如果您已经在服务定义中使用了build属性,并且想要以这种方式进行操作,那么您将被迫以高度自以为是的配置文件污染原本不可知的图像生成器,而该配置文件应该只属于compose和部署过程。

+1用于docker-compose复制功能

+1

+1

+1

+1复制。

+1为docker-compose复制功能。 我认为上述赞成的观点令人信服。

+1复制

+1复制。

虽然在我的视角。 它可能变得很方便,但也可能变得不受控制或为许多用户所滥用,甚至可能使音量过时。 如果您只需要将文件放入容器中(尤其是用于群集),则可以使用配置或密码; 但是就我的情况而言,例如将静态文件夹放入nginx容器中,我必须在Dockerfile中使用多阶段构建将这些静态文件夹放入容器中,这需要很多过程才能实现我的目标。 所以我认为添加复制选项可能非常有用

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1重新开启

+1

+1重新开启

容器(或本身)达到某些状态后,功能是否无法在卷上运行?
它可能是一个类似readonly的标志,但是可以是copyonly ! 然后,您将拥有常规的卷操作管道/语法,并具有在容器内达到同步状态后删除链接的附加功能...

+1重新打开。 批量安装并非始终是一种选择。 这就是为什么我今天在这里发布。 由于一种特殊的情况,即禁止卷挂载,我需要手动修改大量容器来复制文件。

+!

+1

+1用于docker-compose复制功能

+1

+1

我开始认为这毫无意义。 Docker仅在为其构建docker的特定用例周围添加功能-这是用例之外的功能之一,因此他们可能永远不会添加。

+1

@stuaxo只是因为很多人都在要求使用脚枪

在这种情况下,服务运行所需的文件应该被烘焙到构建中(在Dockerfile中声明),可以通过卷使用,或者(在docker stack / Swarm模式的情况下)作为配置存在或秘密物品。 在运行时将文件复制到潜在的多个目标位置很慢,容易出错,并且没有故障恢复能力。

干杯,道歉,如果那是脾气暴躁的话。
当您说“运行服务”时,我想您是说像Web服务这样的长期运行的东西,Docker涵盖了这一方面。

Docker的分层和缓存在其他方面很方便;

我将旧的WordPress博客放入docker,但有时只运行了几分钟,因此我可以导出数据或检查那里的帖子。

使用docker compose分离MySQL和Apache需要花费一些时间,但是我不在乎它们是否都聚集在一起。

在尝试构建诸如Cairo之类的桌面库时,Dockers缓存很有趣。 我试图做的大多数事情都忘记了细节,但是更多地是在构建方面,而不是与运行服务有关。

需要添加+1 docker-compose副本。 它使配置文件和容器更新更加容易。

使用docker cp和docker config

2018年3月2日(星期五)21:19 James Hahn [email protected]写道:

需要添加+1 docker-compose副本。 它使流动更容易
配置文件和对容器的更新。

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/docker/compose/issues/1664#issuecomment-370055493
或使线程静音
https://github.com/notifications/unsubscribe-auth/ABOv-q5VO9n9HDvBP6YJ1BCePz5tGu-pks5tabdrgaJpZM4FTTPg

>

詹姆斯·米尔斯(James Mills)/ prologic

电子信箱
W:prologic.shortcircuit.net.au

+1用于docker-compose复制。 这个想法是有COPYONLY的文件所描述的在这里

+1

+1

在这种情况下,服务运行所需的文件应该被烘焙到构建中(在Dockerfile中声明),可以通过卷使用,或者(在Docker堆栈/ Swarm模式的情况下)作为配置或秘密对象存在。 在运行时将文件复制到潜在的多个目标位置很慢,容易出错,并且没有故障恢复能力。

除了在许多情况下,您想要更新的只是一个配置文件,在这种情况下,烘烤自己的标准官方图像是不好的做法,并且会积for很多技术债务,X10的容量过大而您却没有想要或需要文件保持同步,更不用说必须处理整个文件夹而不是默认位置中的单个文件的问题,并且您需要更新系统文件而不仅仅是获取配置设置。

我了解您的担忧,但是仅告诉所有人他们的需求并不真实,只会使人们远离您的项目以及想要使用它并支持您的工作的社区。 我们想在这里与您一起找到可行的解决方案,但是您只想说我们不需要我们认为需要的解决方案。

哇,我不敢相信这还没有完成。 我认为该基本功能现在已经在docker-compose中了。 哦,OSS项目的美...

docker-compose --force-recreate --rebuild解决了它,如果新文件已更改(或看起来),它将复制新文件。 不理想,但可以。

+1

+1

+1

+1

+1这是低调的驱动力,只为一个配置文件安装一个卷似乎很愚蠢。

+1

我们有一种方法可以使用docker compose卷将文件添加到容器中。 我注意到Compose文档现在确实具有configs设置,因此我们也可以添加单个文件。

https://docs.docker.com/compose/compose-file/#configs

但是,我相信人们想要的是一种将主机中的文件合并到容器中的目录中的方式,优先级为overwrite if exists ,即您期望复制工作的方式。

我很奇怪,撰写文件中的volumes配置具有nocopy选项:

https://docs.docker.com/compose/compose-file/#volumes

volumes:
  - type: volume
  source: mydata
  target: /data
  volume:
    nocopy: true

描述如下:
volume: configure additional volume options
nocopy: flag to disable copying of data from a container when a volume is created

因此,它完全禁用了所需的功能吗?

我想要的用例是用于开发的Web应用程序。 我希望图像包含服务网站所需的一切,包括要服务的默认网站,但我可以选择以网站的当前工作状态合并/覆盖这些文件,而无需使用其他配置(键),而无需将文件包含在其中。在主机上的正确位置。 复制到容器中的文件是临时文件。 表示不在网络共享中。

可以从中受益的框架的一个例子是Laravel。 我制作的图像无需其他配置(卷,网络共享等)即可提供Laravel启动页面的功能,但是编写了compose文件,将文件从主机复制到容器的Laravel根目录,以便可以被覆盖。

为此,使用网络共享对于临时环境来说是一个额外的维护(发展并不总是恒定的)。 为此,使用带有Laravel之类的框架的卷挂架要求在该卷中构建应用程序,这意味着在主机上安装PHP和Composer或共享将在其上创建应用程序的主机上的位置。 两者都造成更多维护。

编辑:

经过测试,似乎在装载卷时,该位置映像中存在的文件将优先于该卷的原始内容复制到永久卷。 意味着它不会覆盖。

我实际上认为这是实现预期结果的解决方案。

嘿,伙计们,仅供参考,最好是在此问题上对最重要的消息给予赞许的反应,而不是添加“ +1”注释,因为问题可以根据他们收到的反应数量进行排序。

+1

+1请Docker团队考虑您的社区。

@ shin-现在的问题是,卷功能使得无法将单个配置文件从外部卷插入到容器中。

假设我想将nginx配置文件插入/etc/something/whatever.conf而又不破坏该文件夹中的所有其他内容。 您不能为单个文件创建命名卷(请参见moby / moby#30310),也不能创建包含单个文件的目录卷,然后将特定文件安装到容器中(请参见moby / moby# 32582)。

剩下的唯一选择是使用配置文件污染实际Docker主机中的固定位置,然后将其绑定安装。如果您想在Docker主机之间移动或使用Docker,这当然很重要。您没有文件系统访问权限的主机(例如,在线CI),或者甚至只是并行运行多个堆栈。

这里必须要让位,要么需要更改Docker中的卷功能,以便我们可以实际使用它来完成将配置文件注入到堆栈中的工作,要么需要使用copy类的方法来解决它

FWIW我不再是Compose维护者,但在我看来,通过在构建时使用Dockerfile注入配置文件可以最好地解决该用例。

@ shin-不幸的是,配置文件在构建时并不知道,映像是在CI服务器上准备好很久的,之后我们才知道我们将在何处部署它们以及采用何种配置。

我在@masaeedu上工作,我了解保持compose功能不爬行的概念性理想,因此不想添加此功能,但是在现实生活中,此功能的丧失极大地减少了无需使用compose的情况

A)必须将某种丑陋的脚本工作凑在一起,以站起有问题的容器(composite的目的是帮助标准化并使我们不必做),

B)必须添加一些其他工具来处理我们的所有配置(虽然可行,但对于中小型项目而言,这实际上需要将特定的.conf和.env复制到每个容器中,这会增加大量的开销,您需要不想在映像生成时执行此操作,这相当于说您应该将所有选项硬编码到C ++中,而不是将软件包含配置文件,否则将需要维护许多额外的映像),或者

C)必须为每次需要的给定软件的每个可能配置维护一个单独的映像/每次我们必须进行较小的配置更改时都要构建一个自定义映像....这在现实世界中都是行不通的生产软件,也使我们无法获得生产软件所需的强大的质量检查和测试管道。

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