如何在docker-compose中将本地文件夹绑定到多个服务,而无需每次都重复?

huangapple go评论68阅读模式
英文:

How to bind mount a local folder into several services in docker-compose, without having to repeat each time?

问题

我有一个docker-compose.yml文件,在其中定义了多个服务,每个服务都对应一个独立的容器。简而言之,它看起来像这样:

version: "3.9"
services:
    dev_1:
        build:
            context: .
            dockerfile: ./Dockerfile
            target: dev_1

        volumes:
            -   type: bind
                source: /home/foo
                target: /home/bar

    dev_2:
        build:
            context: .
            dockerfile: ./Dockerfile
            target: dev_2

        volumes:
            -   type: bind
                source: /home/foo
                target: /home/bar

您可以看到,对于每个服务,我都必须再次绑定挂载卷,复制相同的代码行。但在我的应用程序中,我有多个这样的文件夹,我希望将它们挂载到所有服务中,而不必一遍又一遍地复制所有这些行。

有没有一种方法可以缩短这个过程,例如使用volumes指令?

到目前为止,我只找到了建议使用共享卷,但这对我来说不实用,因为这样的卷会复制数据到卷中。但我有大量数据(几千兆字节),我不想复制它,我只想绑定挂载它。

Docker Compose的版本无关紧要 - 我现在使用的是3.9。只要它能工作,一切都可以。

提前感谢!

英文:

I have a docker-compose.yml file where I'm defining several services, each resulting in an individual container. In short it looks like this:

version: "3.9"
services:
    dev_1:
        build:
            context: .
            dockerfile: ./Dockerfile
            target: dev_1

        volumes:
            -   type: bind
                source: /home/foo
                target: /home/bar

    dev_2:
        build:
            context: .
            dockerfile: ./Dockerfile
            target: dev_2

        volumes:
            -   type: bind
                source: /home/foo
                target: /home/bar

You can see that for each service I have to bind mount the volume again, by copying the same lines of code. But in my application I have several such folders which I want to mount into all the services, but without having to copy all the lines again and again.

Is there a way to shorten this, e.g. by using the volumes directive?

So far I only found suggestions to use a shared volume, but this is not practical for me, as such a volume copies the data into the volume. But I have plenty of data (Terrabytes) which I don't want to copy. I just want to bind mount it.

The docker compose version doesn't matter - right now I'm using 3.9. As long as it works everything is allowed.

Thanks in advance!

答案1

得分: 1

我在Medium上找到了一个解决我的问题的答案:

使用锚点(anchors)、别名(aliases)和x-标记,可以在一个中心服务中定义卷,然后在其他服务中重复使用它们:

version: "3.9"

x-volumes_all: &volumes_all
    volumes:
        - &vol1 /home/foo1:/home/bar1
        - &vol2 /home/foo2:/home/bar2

services:
    <<: *volumes_all
    dev_1:
        build:
            context: .
            dockerfile: ./Dockerfile
            target: dev_1

        volumes:
            - *vol1

    dev_2:
        build:
            context: .
            dockerfile: ./Dockerfile
            target: dev_2

        volumes:
            - *vol2

首先,我将x-volumes_all定义为通用服务,前面的x-表示该服务是隐藏的,仅用于在其他服务中重复使用。此外,我使用锚点&来为其指定一个任意名称(&volumes_all)。在卷部分,我简单地定义了绑定挂载点,再次使用锚点来为每个卷命名(&vol1&vol2)。

随后,在我的服务部分,我通过使用*来取消引用别名,导入隐藏的服务(<<: *volumes_all)。以同样的方式,我现在可以包含各个卷,再次使用*和它们的各自名称。

这样我减少了错误,因为我只需要一次定义所有内容。

在此处找到:
使用Docker Compose文件中的锚点、别名和扩展来避免重复

谢谢大家!🙂

英文:

I found an answer on medium, that solves my problem:
using anchors, aliases and the x-flag makes it possible to define the volumes in a central service, which can then be reused in the other services:

version: &quot;3.9&quot;

x-volumes_all: &amp;volumes_all
    volumes:
        - &amp;vol1 /home/foo1:/home/bar1
        - &amp;vol2 /home/foo2:/home/bar2

services:
    &lt;&lt;: *volumes_all
    dev_1:
        build:
            context: .
            dockerfile: ./Dockerfile
            target: dev_1

        volumes:
            -   *vol1

    dev_2:
        build:
            context: .
            dockerfile: ./Dockerfile
            target: dev_2

        volumes:
            -   *vol2

At first, I define x-volumes_all as the common service - the preceding x- indicates that the service is hidden and only there to be reused in other services. Additionally, I use the anchor &amp; to give it an arbitrary name (&amp;volumes_all). In the volumes section I simply define my bind mounts, again using anchors to give each volume a name (&amp;vol1 and &amp;vol2).

Later, in my service section I import the hidden service (&lt;&lt;: *volumes_all) by dereferencing the alias using *. In the same way I can now include the individual volumes, called again by * and their respective name.

That way I reduce errors as I only need to define everything once.

Found here:
Don’t Repeat Yourself with Anchors, Aliases and Extensions in Docker Compose Files

Thanks folks! 😎

huangapple
  • 本文由 发表于 2023年2月23日 23:44:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75547122.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定