我在Windows的Docker桌面中。我正在尝试使用docker-compose作为构建容器,它在其中构建我的代码,然后代码在我的本地构建文件夹中。构建过程肯定会成功;当我exec
进入容器时,文件在那里。但是,我的本地文件夹没有任何反应-没有创建build
文件夹。
version: '3'
services:
front_end_build:
image: webapp-build
build:
context: .
dockerfile: Dockerfile
ports:
- 5000:5000
volumes:
- "./build:/srv/build"
FROM node:8.10.0-alpine
EXPOSE 5000
# add files from local to container
ADD . /srv
# navigate to the directory
WORKDIR /srv
# install dependencies
RUN npm install --pure-lockfile --silent
# build code (to-do: get this code somewhere where we can use it)
RUN npm run build
# install 'serve' and launch server.
# note: this is just to keep container running
# (so we can exec into it and check for the files).
# once we know that everything is working, we should delete this.
RUN npx serve -s -l tcp://0.0.0.0:5000 build
我还尝试过删除该文件夹的最后一行。然后我确实得到了一个构建文件夹,但是那个文件夹是空的。
更新: 我还尝试了一个多阶段构建:
FROM node:12.13.0-alpine AS builder
WORKDIR /app
COPY . .
RUN yarn
RUN yarn run build
FROM node:12.13.0-alpine
RUN yarn global add serve
WORKDIR /app
COPY --from=builder /app/build .
CMD ["serve", "-p", "80", "-s", "."]
未设置卷(或设置为诸如./build:/nonexistent
之类的不存在的源目录)时,该应用已正确提供,并且我在本地计算机上得到一个空的build文件夹(为空,因为源文件夹不存在。
但是,当我将volumes
设置为- "./build:/app"
(构建文件的正确来源)时,我不仅在本地计算机上看到一个空的build
文件夹,{容器中的{1}}文件夹也为空!
看来发生了什么事
1.构建容器,该容器在构建器中构建文件。
2.文件从构建器复制到第二个容器。
3.卷已链接,然后由于我的本地app
文件夹为空,因此容器上其链接的文件夹也为空!
我尝试重置共享驱动器凭据,但无济于事。
我该怎么做?!?!
答案 0 :(得分:1)
我相信您会误解主机卷的工作方式。体积定义:
./build:/srv/build
在撰写文件中,将从主机内./build
的{{1}}装入容器中。这是在运行时发生的,而不是在映像构建期间发生的,因此是在执行Dockerfile指令之后。映像中的任何内容都不会复制到主机,并且在该目录顶部安装的目录中的文件也不会可见(这是Linux mount命令的标准行为)。
如果您需要将文件从容器中复制回主机,则有多种选择。
作为容器运行的一部分,您可以执行一些步骤来填充构建文件夹。这在开发中很常见。为此,您的/srv/build
可能会变成要运行的多个命令的脚本,最后一步是运行应用程序的CMD
。
您可以切换到命名卷。 Docker将使用映像的内容对其进行初始化。甚至有可能在主机上的文件夹中创建命名绑定安装,这与主机安装几乎相同。有一个名为绑定绑定in my presentation here的示例。
您的容器入口点可以在启动时将文件复制到主机装载中。这通常会在未知情况下运行的图像上看到,例如詹金斯(Jenkins)形象就是这样做的。我也在示例base image的保存/加载卷脚本中执行此操作。
答案 1 :(得分:0)
tl; dr; 在构建阶段不会挂载卷,只有在运行容器时才挂载。您可以运行命令docker run <image id> -v ./build/:/srv/build cp -R /app /srv/build
将数据复制到本地磁盘
在Docker构建映像的同时,它正在 ephemeral 容器中执行所有操作,而您在Dockerfile中拥有的每个命令都在单独的容器中运行,每个命令都构成一个最终成为最终映像的层。
其结果是,构建期间的数据流是单向的,您无法将卷从主机装载到容器中。运行构建时,您会看到Sending build context to Docker daemon
,因为本地Docker CLI正在发送 context (您在docker build
之后指定的路径,通常是.
代表当前目录)到Docker守护程序(实际完成工作的进程)。要记住的一个关键点是,Docker CLI(docker
)实际上并没有做任何工作,它只是向Docker Daemon dockerd
发送命令。构建阶段不应更改本地系统上的任何内容,该容器旨在将更改仅封装到容器映像中,并为您提供可以一致地重复使用的构建快照,内容是一样的。