无法在Docker Windows的docker-compose中绑定主机卷

时间:2019-02-03 06:16:59

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

我一直在试图解决这个问题,似乎是永恒的,但似乎Windows的Docker直到最近才能够将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似乎坏了。

希望你们中的一个能帮助我!在这里感觉很深。

版本

about docker

1 个答案:

答案 0 :(得分:1)

那是一条漫长的路。

但是,我学到了一些东西:我实际上对Docker中的卷挂载工作原理有一个基本的误解。令我惊讶的是,包括相对体积路径在内的所有东西都按预期工作。

我对批量安装的基本误解是,它们在构建步骤中不可用,但是该安装是连接到最终容器上的。 Docker施加了这一要求,因为没有它,构建将无法重复。

所以,在用例I中的Dockerfiledocker run命令之间,唯一的区别(尽管不是很明显,直到我理解这一点),是我的Dockerfile是积极docker run仅在预先构建的alpine上运行命令的情况下,构建容器并尝试执行命令。

那么,有可能做我在做的事情吗? 排序的

我跑进一对夫妇利用一个装饰肥胖型entrypoint.sh链式图案,允许你链多Dockerfile生成输出到其最终容器中,并且当它的运行,执行链接的命令奶酪解决方案的在给定的CMD之前。简而言之,您有一堆全部以ENTRYPOINT ["entrypoint.sh"]结尾的dockerfile,然后概述了先前将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,然后按我的顺序运行在构建过程中需要。我不从依赖缓存这种方式中获益,但我也并不需要它为这个特殊的使用情况。

感谢阅读,希望您也能学到一些东西!