19

我对如何使用命名数据卷(而不是数据容器)感到困惑。

我有一个app_src安装到的命名数据卷/usr/src/app使用 docker compose 文件但是,在(本地)对我的源代码进行更改后,构建映像不会更新卷。

我正在像这样构建图像,

docker-compose -f development.yml build并运行它docker-compose -f development.yml up -d

为了确认卷没有改变,我附加到正在运行的容器中,并且确实,源代码没有更新。

这是我的 docker compose 文件development.ymlDockerfile我的web服务。版本:'2'

services:
  web:
    restart: always
    build: ./web
    expose:
      - "8000"
    volumes:
      - app_src:/usr/src/app
    links:
      - postgres:postgres
    env_file: development.env
    command: ./start_web.sh

volumes:
   app_src: {}


FROM python:3.4.4

WORKDIR /usr/src/app
RUN rm -rf /usr/src/app/*
COPY . /usr/src/app/
RUN pip install --no-cache-dir -r requirements.txt

我可以通过像这样安装主机来使其工作,

volumes:
    - ./web/src:/usr/src/app

我在运行 docker 1.11.2 的 Ubuntu 16.04 上。我的理解错了吗?我确实查看了文档,但我可以找到任何可以很好地解释该卷的内容。

4

3 回答 3

15

看起来您正在尝试使用带有命名卷挂载和 Dockerfile 的 docker-compose 来修改该位置的内容。这不起作用,因为 Dockerfile 正在创建映像。docker-compose 正在定义在该映像之上运行的运行容器。您将无法在创建映像时修改该卷,因为该卷仅在创建映像并运行容器后才挂载。

如果要更新命名卷,请考虑使用一个侧容器:

docker run -v app_src:/target -v `pwd`/web/src:/source --rm \
  busybox /bin/sh -c "tar -cC /source . | tar -xC /target"

您可以按需运行该容器来更新您的命名卷。如果您对大型存储库进行小幅更改,您还可以将 tar 替换为git clone从源存储库中提取的东西,或者甚至是 rsync(您需要将其安装在映像上)。

您还可以通过清空命名卷( rm -rf /vol/dir 或删除卷并创建一个新卷)然后重新启动容器来解决此问题。在容器启动时,如果包含一个空的命名卷,则默认是将该位置的图像内容复制到该卷中。

于 2016-07-18T19:43:10.153 回答
2

一种解决方法是重新创建卷,当然,如果您能承受更长的停机时间:

docker-compose down && docker volume rm <VOLUME_NAME> && docker-compose up -d
于 2020-09-24T09:14:18.113 回答
2

您将卷多次安装到同一个地方。第一次容器将数据存储到主机文件系统中,第二次它从主机文件系统覆盖数据进入容器。从您的 docker-compose 文件中删除卷挂载

volumes: - ./web/src:/usr/src/app #remove this!

你可以在这里获得更多信息

$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

此命令将主机目录 /src/webapp 挂载到位于 /opt/webapp 的容器中。如果路径 /opt/webapp 已存在于容器的映像中,则 /src/webapp 挂载会覆盖但不会删除预先存在的内容。移除挂载后,即可再次访问内容。这与 mount 命令的预期行为一致。

于 2016-07-18T18:10:50.893 回答