docker - 无法在 docker-compose 中为 Docker Windows 绑定主机卷
问题描述
我一直在尝试解决这个问题,这似乎是一个永恒的问题,但似乎 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
但是,给定 a 中的相同实现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 强加了这个要求,因为没有它,构建将无法重复。
因此,在我上面提供的用例中,theDockerfile
和docker run
命令之间的唯一区别(尽管在我理解这一点之前并不明显)是我Dockerfile
正在积极构建一个容器,并尝试执行命令,其中docker run
仅运行命令预建的alpine
.
那么,有可能做我正在做的事情吗?有点
我遇到了几个使用装饰器entrypoint.sh
链接模式的奶酪解决方案,允许您将多个Dockerfile
构建输出链接到它们的最终容器中,并且当它运行时,在给定的CMD
. 简而言之,你有一堆 dockerfiles 都以 结尾ENTRYPOINT ["entrypoint.sh"]
,然后概述了你以前利用的步骤RUN
:
- ls.docker 文件
- mod.docker文件
- final.docker文件
#!/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
命令推迟到 final ENTRYPOINT
,创建一个奇异entrypoint.sh
的 ,然后在构建期间按照我想要的顺序运行它们。我不会以这种方式从依赖缓存中受益,但对于这个特定的用例,我也不需要它。
感谢阅读,我希望你也学到了一些东西!
推荐阅读
- javascript - Webpack - 输出不同的文件扩展名?
- android - WebView 在模拟器上显示动画 GIF 并在真实设备上显示静态图像
- java - 带有模拟的单元测试在 IntelliJ 中工作,Maven 失败
- wso2 - 在 WSO2(5 版以上)的 API 管理器中更改密码后如何发布自定义 API?
- javascript - 在地图中反应原生特定样式项目
- sql - 使用新数据更新表
- azure - Azure 存储同步机制
- html - HTML5 视频突然不工作,以前工作
- webview - Nativescript Webview 问题
- python - ETL过程中数据库中重复记录的问题