Docker卷未安装/链接

时间:2019-11-08 19:22:26

标签: docker docker-compose dockerfile docker-volume

我在Windows的Docker桌面中。我正在尝试使用docker-compose作为构建容器,它在其中构建我的代码,然后代码在我的本地构建文件夹中。构建过程肯定会成功;当我exec进入容器时,文件在那里。但是,我的本地文件夹没有任何反应-没有创建build文件夹。

docker-compose.yml

version: '3'
services:
  front_end_build:
    image: webapp-build
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 5000:5000
    volumes:
      - "./build:/srv/build"

Dockerfile

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文件夹为空,因此容器上其链接的文件夹也为空!

我尝试重置共享驱动器凭据,但无济于事。

我该怎么做?!?!

2 个答案:

答案 0 :(得分:1)

我相信您会误解主机卷的工作方式。体积定义:

./build:/srv/build

在撰写文件中,将从主机内./build的{​​{1}}装入容器中。这是在运行时发生的,而不是在映像构建期间发生的,因此是在执行Dockerfile指令之后。映像中的任何内容都不会复制到主机,并且在该目录顶部安装的目录中的文件也不会可见(这是Linux mount命令的标准行为)。

如果您需要将文件从容器中复制回主机,则有多种选择。

  1. 作为容器运行的一部分,您可以执行一些步骤来填充构建文件夹。这在开发中很常见。为此,您的/srv/build可能会变成要运行的多个命令的脚本,最后一步是运行应用程序的CMD

  2. 您可以切换到命名卷。 Docker将使用映像的内容对其进行初始化。甚至有可能在主机上的文件夹中创建命名绑定安装,这与主机安装几乎相同。有一个名为绑定绑定in my presentation here的示例。

  3. 您的容器入口点可以在启动时将文件复制到主机装载中。这通常会在未知情况下运行的图像上看到,例如詹金斯(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发送命令。构建阶段不应更改本地系统上的任何内容,该容器旨在将更改仅封装到容器映像中,并为您提供可以一致地重复使用的构建快照,内容是一样的。