为什么我的docker-compose卷没有通过本地文件添加进行更新?

时间:2019-06-02 07:54:39

标签: django docker nginx docker-compose docker-volume

这是我的docker-compose.yml,它包含一个Web服务,该服务在本地安装文件夹,以便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中创建一个新文件(在webappnginx服务之间作为共享卷装入的同一文件夹)时,我从运行中看不到该文件。 webapp容器。

但是,如果我在web/文件夹中的其他任何地方创建了一个新文件(该文件也作为单独的卷挂载),我会从正在运行的webapp容器内部看到更改。

是什么原因造成的?以及如何更改这种行为?

(我需要能够从正在运行的容器中运行python manage.py collectstatic,但需要输出到本地硬盘驱动器的web/public中,以便构建用于部署的生产Docker映像。)

2 个答案:

答案 0 :(得分:1)

我看不到这里的东西有问题。我复制了您的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:

网络/ Dockerfile

FROM ubuntu:18.04

CMD tail -f /dev/null

nginx / Dockerfile

FROM nginx:latest

CMD tail -f /dev/null

演示:

docker-volumes

要详细说明DannyB的上述评论,请确保您没有在web/public的主机上创建文件,因为在容器启动时将挂载此文件夹。 docker卷的工作方式类似于标准linux挂载-docker只会将新卷挂载在现有目录的顶部。

如果您想在Docker容器内运行命令以更改主机文件系统上的文件,请不要使用Docker卷-而是像在此处一样使用bind mount- ./web/:/usr/src/app/

绑定安装码头工人卷之间的区别在于,绑定安装将从容器中的主机中装载文件,并将依赖于这些文件夹/文件在您的主机文件系统上,并且docker卷将完全由docker管理,并且只能在容器之间共享,而不能与主机共享(尽管这些文件确实存在于主机上的某个位置,但跟踪和尝试它们并不可行使用它们。)

实际上您可以从docker-compose文件中删除 docker卷,并为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

演示:

enter image description here

答案 1 :(得分:1)

您已经告诉Docker from tkinter import * from tkinter import ttk import multiprocessing def print1(): global a while a is True: print('im process 1') def print2(): global a while a is True: print('im process 2') def start(): process1.start() process2.start() def stop(): process1.kill() process2.kill() a = True if __name__ == '__main__': process1 = multiprocessing.Process(target=print1) process2 = multiprocessing.Process(target=print2) root = Tk() root.title("Title") root.geometry("200x200") app = Frame(root) app.grid() start = ttk.Button(app, text="Start", command=start) stop = ttk.Button(app, text="Stop", command=stop) start.grid(padx=15, pady=20) stop.grid(column=1, row=0) root.mainloop() process1.join() process2.join() 包含必须在容器的各个运行之间保留的关键应用程序数据。容器第一次启动,并且只有第一次,Docker将从图像中填充它。如果稍后更新映像,由于该卷包含关键的应用程序数据,因此Docker不会更改它。

最简单的短期解决方法是删除该卷。尝试staticfile_volume。每当您更改静态内容时,都需要执行此操作。

从长远来看,将后端应用程序配置为提供自己的文件会容易一些。 Django有一个django.contrib.staticfiles模块来执行此操作。然后,您的nginx代理可以无条件地重定向到后端容器,而您不必担心文件共享问题。

(要更好地了解这一点,请使用@ChrisMcKinnel的复制配方并运行一次。然后从此处获取docker-compose down -v; docker-compose up --build并将web/Dockerfile的文件放入COPY中,然后重新运行{{1 }}。除非您/usr/src/app/public,否则您不会看到该文件。)

相关问题