【问题标题】:Bind Mount & Volumes: Files do not end up in the container?绑定挂载和卷:文件最终不会在容器中?
【发布时间】:2019-05-12 10:04:40
【问题描述】:

我正在为一个奇怪的问题而苦恼。我正在将一个文件夹从主机安装到容器(仅用于开发)。该文件夹称为dj_docker,并有一个文件夹dj_docker/media,其中包含一些.pdf 文件,这些文件需要最终保存在容器中,并且必须可以通过卷media_volume 被其他容器访问。但是,一旦我将子目录/media 映射到卷(绑定挂载以及卷现在包括文件夹/media),该文件夹的所有内容就会消失在容器中。文件夹为空。

简化的 docker-compose.yml:

version: '3.7'

services:
  restapi:
    volumes: 
      - media_volume:/usr/src/dj/media
      - ./dj_docker:/usr/src/dj/
volumes:
  static_volume:
  media_volume:

如果我省略 docker-compose 文件中的卷,则 .pdf 文件可见并存在于容器中:

    volumes: 
      - ./dj_docker:/usr/src/dj/

有没有办法在我将文件保存在容器中时仍然使用绑定挂载以及卷?

Dockerfile

# pull official base image
FROM python:3.7-alpine

# set environment varibles
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# set work directory
WORKDIR /usr/src/dj

# install psycopg2
RUN apk update \
    && apk add --virtual build-deps gcc python3-dev musl-dev \
    && apk add postgresql-dev \
    && pip install psycopg2 \
    && apk del build-deps

# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt /usr/src/dj/requirements.txt
RUN pip install -r requirements.txt
VOLUME /usr/src/dj/media

# copy entrypoint.sh
COPY ./entrypoint.sh /usr/src/dj/entrypoint.sh

# run entrypoint.sh
ENTRYPOINT ["/usr/src/dj/entrypoint.sh"]

【问题讨论】:

  • 你没有重复的路径吗? dj 文件夹包含被 media_volume 覆盖的媒体文件夹
  • 是的,我怀疑会发生这种情况(尽管预期的行为会是合并)......但我仍然需要从容器/卷中的本地机器获取文件
  • 嗯,这不可能合并...你需要为卷设置不同的路径
  • @Xen_mar 很抱歉给您带来不便。我同意具有 2 条不同路径的解决方案。如果您还没有这样做,您可以通过在 entrypoint.sh 中添加类似“cp -R /usr/src/dj/media/* /pdfs/”之类的内容来进一步自动化它。其中 /pdfs 是外部卷的容器挂载目录(- media_volume:/pdfs)。这将在每次重新启动服务时更新您的卷,无需在容器内进行手动操作。希望这会有所帮助

标签: docker docker-compose docker-volume


【解决方案1】:

有没有办法在我将文件保存在容器中时仍然使用绑定挂载以及卷?

不,这是不可能的。

这与普通的 Un*x mount(8) 相同(事实上,如果您使用低级工具四处寻找,您会在 Docker 设置中看到文件系统安装)。卷挂载完全隐藏了之前目录中的所有内容。如果你有这样的分层挂载,Docker 会在应用之前对它们进行排序,最里面的目录挂载会在下一个最外面的挂载中隐藏该目录中的内容。

这里最容易更改的可能是保存这些数据的容器端目录。我可能会在应用程序的安装树之外选择一个根目录路径,例如 /media。通过环境变量设置位置(在非 Docker 开发环境中有所不同)。如果种子内容不存在,则在启动时将其复制到那里(现在不会被卷安装隐藏)。

【讨论】:

  • 嘿大卫,谢谢你的回答。我已经尝试过你的方法并让它发挥作用。这有点令人沮丧,因为我的 dockerized dev-server 使用热重载,现在无法使用更新的静态文件执行此操作,因为我必须重新启动服务才能将静态文件复制到图像。还是谢谢你。
  • @DavidMaze 我真的相信我的解决方案会奏效,因为我可以发誓我以前解决过类似的问题。但是由于我无法证明(并且我尝试过),所以我承认您是对的。我仍然不同意 VOLUME 没用,但它确实不能解决这个问题。
【解决方案2】:

您可以同时拥有主机卷和命名卷,但有一个技巧可以让它发挥作用。这篇文章应该可以解决你的问题:https://jdlm.info/articles/2019/09/06/lessons-building-node-app-docker.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 2017-07-21
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多