为什么我的 docker-compose 卷没有更新本地文件添加?
Why doesn't my docker-compose volume get updated with local file additions?
这是我的 docker-compose.yml
,它包含一个网络服务,它在本地安装一个文件夹,以便在任何代码更改时 watchmedo
重新启动 webapp
django 服务器。它是 nginx 的反向代理。
version: '3'
services:
webapp:
build:
context: .
dockerfile: ./web/Dockerfile
volumes:
- ./web/:/usr/src/app/
- staticfile_volume:/usr/src/app/public
entrypoint: >
watchmedo auto-restart --recursive
--pattern="*.py" --directory="."
gunicorn myapp.wsgi:application -- --bind 0.0.0.0:9000
nginx:
build:
context: .
dockerfile: ./nginx/Dockerfile
depends_on:
- webapp
volumes:
- staticfile_volume:/usr/src/app/public
volumes:
staticfile_volume:
我的本地文件设置如下:
$ tree -L 2
.
├── docker-compose.yml
├── nginx
│ ├── Dockerfile
│ └── nginx.conf
└── web
├── Dockerfile
├── manage.py
├── myapp
├── public
└── static
但是当我在 web/public
中创建一个新文件时(在 webapp
和 nginx
服务之间作为共享卷安装的同一文件夹),我从内部看不到它运行ning webapp
容器。
然而,如果我在 web/
文件夹(也作为单独的卷安装)中的其他任何位置创建一个新文件,我会从 运行ning [=15] 中看到更改=] 容器。
这是什么原因造成的?我该如何改变这种行为?
(我需要能够从 运行ning 容器内部 运行 python manage.py collectstatic
但输出到本地硬盘驱动器的 web/public
以便我可以构建生产Docker 个用于部署的图像。)
我看不出你这里有什么问题。我复制了您的 docker-compose.yml
并仅删除了其中的 entrypoint:
部分,它对我有用。
docker-compose.yml
version: '3'
services:
webapp:
build:
context: .
dockerfile: ./web/Dockerfile
volumes:
- ./web/:/usr/src/app/
- staticfile_volume:/usr/src/app/public
nginx:
build:
context: .
dockerfile: ./nginx/Dockerfile
depends_on:
- webapp
volumes:
- staticfile_volume:/usr/src/app/public
volumes:
staticfile_volume:
web/Dockerfile
FROM ubuntu:18.04
CMD tail -f /dev/null
nginx/Dockerfile
FROM nginx:latest
CMD tail -f /dev/null
演示:
为了详细说明 DannyB 上面的评论,请确保您没有在 web/public
中的主机 上创建文件 ,因为当容器启动时,此文件夹会被挂载. docker 卷的工作方式类似于标准 linux 挂载 - docker 只会将新卷挂载到现有目录的顶部。
如果您想 运行 Docker 容器中的命令更改主机文件系统上的文件,请不要使用 docker 卷 - 而是使用 bind mount 就像你在这里所做的那样:- ./web/:/usr/src/app/
.
bind mount 和 docker volume 之间的区别是 bind mount 将从您的主机挂载文件在您的容器内,并且将依赖于主机文件系统上的那些文件夹/文件,并且 docker 卷将完全由 docker 管理,并且只能在容器之间共享,而不能与主机共享(虽然这些文件确实存在于主机的某个地方,但追踪它们并尝试使用它们是不切实际的)。
你实际上可以从你的 docker-compose
文件中删除你的 docker volume 并为 nginx 添加一个绑定挂载,你将开始看到您追求的行为:
docker-compose.yml
version: '3'
services:
webapp:
build:
context: .
dockerfile: ./web/Dockerfile
volumes:
- ./web/:/usr/src/app/
nginx:
build:
context: .
dockerfile: ./nginx/Dockerfile
depends_on:
- webapp
volumes:
- ./web/public:/usr/src/app/public
演示:
您已告知 Docker staticfile_volume
包含必须在容器的 运行 中保留的关键应用程序数据。容器第一次启动时,只有第一次,Docker 将从图像中填充它。如果您稍后更新映像,由于该卷包含关键的应用程序数据,Docker 不会更改它。
最简单的 short-term 解决方法是删除卷。尝试 docker-compose down -v; docker-compose up --build
。每当您更改静态内容时,您都需要执行此操作。
配置 back-end 应用程序以提供其自己的文件会更容易 long-term。 Django 有一个 django.contrib.staticfiles
模块来执行此操作。那么你的nginx代理就可以无条件的重定向到后端容器,再也不用担心文件共享问题了。
(为了更好地了解这一点,请使用@ChrisMcKinnel 的复制配方并 运行 一次。然后从那里获取 web/Dockerfile
和 COPY
一个文件到 /usr/src/app/public
和re-run docker-compose up --build
。除非你 docker-compose down -v
。你不会看到文件出现。)
这是我的 docker-compose.yml
,它包含一个网络服务,它在本地安装一个文件夹,以便在任何代码更改时 watchmedo
重新启动 webapp
django 服务器。它是 nginx 的反向代理。
version: '3'
services:
webapp:
build:
context: .
dockerfile: ./web/Dockerfile
volumes:
- ./web/:/usr/src/app/
- staticfile_volume:/usr/src/app/public
entrypoint: >
watchmedo auto-restart --recursive
--pattern="*.py" --directory="."
gunicorn myapp.wsgi:application -- --bind 0.0.0.0:9000
nginx:
build:
context: .
dockerfile: ./nginx/Dockerfile
depends_on:
- webapp
volumes:
- staticfile_volume:/usr/src/app/public
volumes:
staticfile_volume:
我的本地文件设置如下:
$ tree -L 2
.
├── docker-compose.yml
├── nginx
│ ├── Dockerfile
│ └── nginx.conf
└── web
├── Dockerfile
├── manage.py
├── myapp
├── public
└── static
但是当我在 web/public
中创建一个新文件时(在 webapp
和 nginx
服务之间作为共享卷安装的同一文件夹),我从内部看不到它运行ning webapp
容器。
然而,如果我在 web/
文件夹(也作为单独的卷安装)中的其他任何位置创建一个新文件,我会从 运行ning [=15] 中看到更改=] 容器。
这是什么原因造成的?我该如何改变这种行为?
(我需要能够从 运行ning 容器内部 运行 python manage.py collectstatic
但输出到本地硬盘驱动器的 web/public
以便我可以构建生产Docker 个用于部署的图像。)
我看不出你这里有什么问题。我复制了您的 docker-compose.yml
并仅删除了其中的 entrypoint:
部分,它对我有用。
docker-compose.yml
version: '3'
services:
webapp:
build:
context: .
dockerfile: ./web/Dockerfile
volumes:
- ./web/:/usr/src/app/
- staticfile_volume:/usr/src/app/public
nginx:
build:
context: .
dockerfile: ./nginx/Dockerfile
depends_on:
- webapp
volumes:
- staticfile_volume:/usr/src/app/public
volumes:
staticfile_volume:
web/Dockerfile
FROM ubuntu:18.04
CMD tail -f /dev/null
nginx/Dockerfile
FROM nginx:latest
CMD tail -f /dev/null
演示:
为了详细说明 DannyB 上面的评论,请确保您没有在 web/public
中的主机 上创建文件 ,因为当容器启动时,此文件夹会被挂载. docker 卷的工作方式类似于标准 linux 挂载 - docker 只会将新卷挂载到现有目录的顶部。
如果您想 运行 Docker 容器中的命令更改主机文件系统上的文件,请不要使用 docker 卷 - 而是使用 bind mount 就像你在这里所做的那样:- ./web/:/usr/src/app/
.
bind mount 和 docker volume 之间的区别是 bind mount 将从您的主机挂载文件在您的容器内,并且将依赖于主机文件系统上的那些文件夹/文件,并且 docker 卷将完全由 docker 管理,并且只能在容器之间共享,而不能与主机共享(虽然这些文件确实存在于主机的某个地方,但追踪它们并尝试使用它们是不切实际的)。
你实际上可以从你的 docker-compose
文件中删除你的 docker volume 并为 nginx 添加一个绑定挂载,你将开始看到您追求的行为:
docker-compose.yml
version: '3'
services:
webapp:
build:
context: .
dockerfile: ./web/Dockerfile
volumes:
- ./web/:/usr/src/app/
nginx:
build:
context: .
dockerfile: ./nginx/Dockerfile
depends_on:
- webapp
volumes:
- ./web/public:/usr/src/app/public
演示:
您已告知 Docker staticfile_volume
包含必须在容器的 运行 中保留的关键应用程序数据。容器第一次启动时,只有第一次,Docker 将从图像中填充它。如果您稍后更新映像,由于该卷包含关键的应用程序数据,Docker 不会更改它。
最简单的 short-term 解决方法是删除卷。尝试 docker-compose down -v; docker-compose up --build
。每当您更改静态内容时,您都需要执行此操作。
配置 back-end 应用程序以提供其自己的文件会更容易 long-term。 Django 有一个 django.contrib.staticfiles
模块来执行此操作。那么你的nginx代理就可以无条件的重定向到后端容器,再也不用担心文件共享问题了。
(为了更好地了解这一点,请使用@ChrisMcKinnel 的复制配方并 运行 一次。然后从那里获取 web/Dockerfile
和 COPY
一个文件到 /usr/src/app/public
和re-run docker-compose up --build
。除非你 docker-compose down -v
。你不会看到文件出现。)