Docker - 无法在卷中的容器之间共享数据(docker-compose 3)

时间:2018-05-18 13:24:57

标签: docker docker-compose docker-volume

我现在有一些用于Web应用程序的容器(nginx,gunicorn,postgres和节点用于从源构建静态文件和React服务器端呈现)。在节点容器的Dockerfile中,我有两个步骤:构建和运行(Dockerfile.node)。它最终在容器内有两个目录:bundle_client - 是nginx和bundle_server的静态 - 它在节点容器本身中用于启动快速服务器。

然后我需要与nginx容器共享一个构建的静态文件夹(bundle_client)。要根据我docker-compose.yml中的docker-compose参考文件执行此操作,我有以下服务(请参阅完整docker-compose.yml):

node:
  volumes:
    - vnode:/usr/src

nginx:
  volumes:
    - vnode:/var/www/tg/static
  depends_on:
    - node

和卷:

volumes:
  vnode:

正在运行docker-compose build完成且没有错误。运行docker-compose up每次都运行正常,我可以打开localhost:80并且有nginx,gunicorn和节点表达SSR都运行良好,我可以看到一个网页,但所有静态文件都返回404找不到错误。

如果我用docker volume ls检查卷,我可以看到两个名为tg_vnode的新创建的卷(我们在这里考虑)和tg_vdata(参见完整的docker-compose.yml)

如果我使用docker run -ti -v /tmp:/tmp tg_node /bin/bash进入nginx容器,我看不到应该从节点卷映射静态文件的www/tg/static文件夹。此外,我尝试使用nginx容器/var/www/tg/static创建一个空的Dockerfile.nginx文件夹,但它仍然是空的。

如果我将bundle_client部分中的docker-compose.yml nginx.volumes部分中的- ./client/bundle_client:/var/www/tg/static文件夹映射为docker volume inspect vnode,它可以正常工作,我可以看到所有提供的静态文件在浏览器中使用nginx。

我做错了什么以及如何让我的容器与nginx容器共享构建的静态内容?

PS:我阅读了所有文档,所有github问题和stackoverflow Q& As,据我所知它必须工作,没有信息什么时候不做。

UPD: [ { "CreatedAt": "2018-05-18T12:24:38Z", "Driver": "local", "Labels": { "com.docker.compose.project": "tg", "com.docker.compose.version": "1.21.1", "com.docker.compose.volume": "vnode" }, "Mountpoint": "/var/lib/docker/volumes/tg_vnode/_data", "Name": "tg_vnode", "Options": null, "Scope": "local" } ] 的结果:

npm install

文件: Dockerfile.nodedocker-compose.yml

Nginx dockerfile:Dockerfile.nginx

UPD:我创建了一个简化的repo来重现一个问题:repolocalhost:80上有一些警告,没关系,安装和构建正常。最后,当我们打开vendor.js时,我们会在Chrome开发工具中看到一个空白页面和404条消息,其中包含静态文件(app.jsReact app: static loaded),但应该会生成一条消息$(document).on('click', 'table td', function() { $(this) .popup({ popup: $('.custom.popup') }); });反应脚本。

2 个答案:

答案 0 :(得分:8)

您需要进行两项更改。在您的节点服务和广告中,如

volumes:
  - vnode:/usr/src/bundle_client

由于您要共享/usr/src/bundle_client,因此您不应该使用/usr/src/,因为它也会共享整个文件夹和结构。

然后在你的nginx服务中添加像

这样的卷
volumes:
  - type: volume
    source: vnode
    target: /var/www/test/static
    volume:
      nocopy: true

nocopy: true保持我们的意图清楚,在容器的初始地图上不应复制映射文件夹的内容。默认情况下,要映射到卷的第一个容器将获取映射文件夹的内容。在您的情况下,您希望它是node容器。

同样在测试之前,请确保在命令下运行以终止缓存卷

docker-compose down -v

您可以在我的测试中看到容器有文件

Nginx has files

答案 1 :(得分:1)

逐步说明发生的事情

Dockerfile.node

    ...
    COPY ./client /usr/src
    ...

搬运工-compose.yml

services:
  ...
  node:
    ...
    volumes:
      - ./server/nginx.conf:/etc/nginx/nginx.conf:ro
      - vnode:/usr/src
  ...
volumes:
  vnode:
  1. docker-compose up使用此Dockerfile.node和docker-compose部分创建命名卷,并将数据保存在/ usr / src中。
  2. Dockerfile.nginx

    FROM nginx:latest
    
    COPY ./server/nginx.conf /etc/nginx/nginx.conf
    
    RUN mkdir -p /var/www/tg/static
    
    EXPOSE 80
    EXPOSE 443
    
    CMD ["nginx", "-g", "daemon off;"]
    
    1. 这会产生使用docker-compose创建的nginx容器将为空/var/www/tg/static/
    2. 搬运工-compose.yml

       ...
       nginx:
          build:
            context: .
            dockerfile: ./Dockerfile.nginx
          container_name: tg_nginx
          restart: always
          volumes:
            - ./server/nginx.conf:/etc/nginx/nginx.conf:ro
            - vnode:/var/www/tg/static
          ports:
            - "80:80"
            - "443:443"
          depends_on:
            - node
            - gunicorn
          networks:
            - nw_web_tg
      
       volumes:
         vdata:
         vnode:
      
      1. docker-compose up将生成vnode命名卷,并使用/var/www/tg/static(现在为空)到现有vnode的数据填充。
      2. 所以,在这一点上,   - nginx容器有/ var / www / tg / static为空,因为它是空的(请参阅Dockerfile.nginx中的mkdir)   - 节点容器有/ usr / src dir和客户端文件(参见在Dockerfile.node中复制的)   - vnode的内容为来自node的/ usr / src和来自nginx的/var/www/tg/static

          

        明确地说,要将/ usr / src中的数据从node容器传递到/var/www/tg/static容器中的nginx,您需要做一些不太漂亮的事情,因为Docker没有'还开发了另一种方法:您需要将源文件夹中的命名卷与目标中的绑定卷结合起来:

         nginx:
             build:
               context: .
               dockerfile: ./Dockerfile.nginx
             container_name: tg_nginx
             restart: always
             volumes:
               - ./server/nginx.conf:/etc/nginx/nginx.conf:ro
               - /var/lib/docker/volumes/vnode/_data:/var/www/tg/static
             ports:
               - "80:80"
               - "443:443"
             depends_on:
               - node
               - gunicorn
             networks:
               - nw_web_tg
        

        只需按- vnode:/var/www/tg/static

        更改docker-compose - /var/lib/docker/volumes/vnode/_data:/var/www/tg/static