Docker 卷未安装/链接

Jon*_*man 2 docker dockerfile docker-compose 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"

Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我还尝试删除为该文件夹提供服务的最后一行。然后我实际上确实得到了一个构建文件夹,但该文件夹是空的。

更新:我还尝试了多阶段构建:

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", "."]
Run Code Online (Sandbox Code Playgroud)

当我的卷未设置(或者设置为某些不存在的源目录,例如./build:/nonexistent)时,应用程序将正确运行,并且我在本地计算机上得到一个空的构建文件夹(因为源文件夹不存在,所以为空) 。

然而,当我将 my 设置volumes为(构建文件的正确源)时,我不仅在本地计算机上- "./build:/app"得到一个空文件夹,容器中的文件夹也是空的!buildapp

看起来发生的事情类似于 1. 容器已构建,它在构建器中构建文件。2. 文件从构建器复制到第二个容器。3.卷被链接了,然后因为我的本地build文件夹是空的,所以它在容器上的链接文件夹也变成空了!

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

我该怎么做呢?!?!

BMi*_*tch 5

我相信您误解了主机卷的工作原理。体积定义:

./build:/srv/build
Run Code Online (Sandbox Code Playgroud)

撰写文件将从容器内的./build主机挂载。/srv/build这发生在运行时,而不是在镜像构建期间,而是在执行 Dockerfile 指令之后。映像中的任何内容都不会复制到主机,并且挂载在其顶部的目录中的任何文件都将不可见(这是 Linux mount 命令的标准行为)。

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

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

  2. 您可以切换到命名卷。Docker 将使用镜像的内容来初始化它们。甚至可以创建到主机上文件夹的命名绑定挂载,这几乎与主机挂载相同。我的演示中有一个命名绑定安装的示例(此处) 。

  3. 您的容器入口点可以在启动时将文件复制到主机挂载。这在未知情况下运行的镜像上很常见,例如 Jenkins 镜像就是这样做的。我还在示例基本映像的保存/加载卷脚本中执行此操作。