【问题标题】:Unable to bind host volume in docker-compose for Docker Windows无法在 docker-compose 中为 Docker Windows 绑定主机卷
【发布时间】:2019-06-27 06:26:04
【问题描述】:

我一直在尝试解决这个问题,似乎是永恒的,但似乎 Docker for Windows 直到最近才能够成功地将卷从 Windows 主机绑定到其 Docker 容器。但是,我无法通过docker-compose 获得相同的功能。有没有人对此有任何明确的信息,或者关于我如何让它发挥作用的想法?

我已经阅读了大量关于 Windows 卷挂载的 GitHub 问题,但似乎大多数答案都与让 Docker 挂载卷有关。我没有问题,只是docker-compose

为了说明我的问题,以下命令为我提供了以下输出,这是安装在 Docker 中的本地目录的正确内容:

$ docker run --rm -v c:/Users/synta/go/src/github.com/syntaqx/example:/go/src/github.com/syntaqx/example alpine ls /go/src/github.com/syntaqx/example
LICENSE
README.md
cmd
docker-compose.yml
docs
go.mod
go.sum
example.go

但是,如果在 docker-compose.yml 中实现相同的实现:

version: '3.6'
services:
  example:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - /c/Users/syntaqx/go/src/github.com/syntaqx/example:/go/src/github.com/syntaqx/example

还有以下Dockerfile

ARG GO_VERSION=1.11
ARG ALPINE_VERSION=3.8

FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS builder

WORKDIR /go/src/github.com/syntaqx/example
RUN ls -alh

ENTRYPOINT ["go"]

我没有得到任何输出(ls -alh 给出了...,让我知道该目录肯定是通过WORKDIR 存在的,但不是从绑定中填充的):

$ docker-compose up -d --build
Building example
Step 1/6 : ARG GO_VERSION=1.11
Step 2/6 : ARG ALPINE_VERSION=3.8
Step 3/6 : FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS builder
 ---> be1230a1b343
Step 4/6 : WORKDIR /go/src/github.com/syntaqx/example
 ---> Using cache
 ---> a0ccb401a86a
Step 5/6 : RUN ls /go/src/github.com/syntaqx/example
 ---> Running in 0cd52d44a637
Removing intermediate container 0cd52d44a637
 ---> 4f362f738e49
Step 6/6 : ENTRYPOINT ["go"]
 ---> Running in 5d7a1e841bfe
Removing intermediate container 5d7a1e841bfe
 ---> 9da9cfcf372a

...

也许我在这里遗漏了一些明显的东西,但我已经尝试了十几种表达音量 PATH 的方法(.C:\/c////c),相对路径显然非常破碎在 Docker Windows 中,其他路径不会改变结果。

如果这是重复的,也非常抱歉,但据我所知,大多数其他问题都非常具体地试图在 Docker 中挂载主机卷,期间。或者,相对路径的问题,我很乐意暂时避开。重复一遍,所有这些对我来说都很好,如我的示例所示,只是 docker-compose 似乎坏了。

希望你们中的一个可以帮助我!在这里感觉非常超出我的深度。

版本

【问题讨论】:

标签: docker docker-compose docker-volume docker-for-windows


【解决方案1】:

那是一条多么漫长的路啊。

但是,我学到了一些东西:我实际上对卷挂载在 Docker 中的工作方式存在根本性的误解。令我惊讶的是,包括相对音量路径在内的所有内容都按预期工作。

我对卷挂载的基本误解是它们在构建步骤期间不可用,但挂载附加到最终容器。 Docker 强加了这个要求,因为没有它,构建将无法重复。

所以,在我上面提供的用例中,Dockerfiledocker run 命令之间的唯一区别(尽管在我理解这一点之前并不明显)是我的Dockerfile 正在积极构建一个容器,并尝试执行命令,其中docker run 仅在预构建的alpine 上运行命令。

那么,有可能做我正在做的事情吗? 有点

我遇到了几个使用装饰器式 entrypoint.sh 链接模式的奶酪解决方案,允许您将多个 Dockerfile 构建输出链接到它们的最终容器中,并且当它运行时,在给定 @ 之前执行链接命令987654328@。简单地说,你有一堆 dockerfiles 都以ENTRYPOINT ["entrypoint.sh"] 结尾,然后概述你以前利用RUN 的步骤:

  • ls.dockerfile
  • mod.dockerfile
  • final.dockerfile
#!/bin/sh
set -eu

until /go/src/github.com/syntaqx/example && go mod download
do
    echo "Waiting for mount..."
done

sh -c "go $*"

然后,您可以让每个 dockerfile 将命令放在最后一个之上。

注意:我没有使用过一次,如下所述,所以这个 shell 可能不起作用,但我认为这是一个很酷的实现思想,所以我想点头.

但是,对于我的用例来说,所有这些都是非常不必要的。知道命令失败的原因后,我可以简单地将RUN 命令推迟到最后的ENTRYPOINT,创建一个单数entrypoint.sh,然后在构建期间按照我想要的顺序运行它们。这种方式我没有从依赖缓存中受益,但对于这个特定的用例我也不需要它。

感谢阅读,希望你也有所收获!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-11
    • 2019-08-17
    • 2018-09-24
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    相关资源
    最近更新 更多