首页 文章

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

提问于
浏览
8

我现在有一些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容器 Dockerfile.nginx 创建一个空的 /var/www/tg/static 文件夹,但它保持为空 .

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

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

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

UPD: docker volume inspect vnode 的结果:

[
{
    "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"
}
]

文件:Dockerfile.nodedocker-compose.yml

Nginx dockerfile:Dockerfile.nginx


UPD: 我创建了一个简化的仓库来重现一个问题:reponpm install 上有一些警告,从不安装它,并且构建正常) . 最后,当我们打开 localhost:80 时,我们会在Chrome开发工具中看到一个空页面和404个静态文件消息( vendor.jsapp.js ),但应该有反应脚本生成的消息 React app: static loaded .

2 回答

  • 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

    逐步说明会发生什么

    Dockerfile.node

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

    泊坞窗,compose.yml

    services:
      ...
      node:
        ...
        volumes:
          - ./server/nginx.conf:/etc/nginx/nginx.conf:ro
          - vnode:/usr/src
      ...
    volumes:
      vnode:
    
    • docker-compose up 使用此Dockerfile.node和docker-compose部分创建 named volume ,数据保存在/ usr / src中 .

    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;"]
    
    • 产生用 docker-compose 创建的nginx容器将为空 /var/www/tg/static/

    泊坞窗,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:
    
    • docker-compose up 将生成 vnode 命名卷,并将 /var/www/tg/static (现在为空)中的数据填充到现有vnode .

    所以,在这一点上, - nginx容器有/ var / www / tg / static为空,因为它是空的(参见Dockerfile.nginx中的mkdir) - 节点容器有/ usr / src dir和客户端文件(见复制到Dockerfile.node) - vnode的内容为/ usr / src,来自 node/var/www/tg/static 来自nginx .

    最后,要将数据从/ usr / src从节点容器传递到nginx容器中的/ var / www / tg / static,你需要做一些不太漂亮的事情,因为Docker还没有开发另一种方法:你需要将源文件夹中的命名卷与目标中的绑定卷组合:nginx:
    Build :
    背景: .
    dockerfile:./ Dockerfile.nginx
    container_name:tg_nginx
    重启:总是
    卷:

    • ./server/nginx.conf:/etc/nginx/nginx.conf:ro
    • / var / lib / docker / volumes / vnode / _data:/ var / www / tg / static
      端口:
    • “80:80”
    • “443:443”
      依赖于取决于:
    • 节点
    • gunicorn
      网络:
    • nw_web_tg

    Just change in docker-compose - vnode:/var/www/tg/static by - /var/lib/docker/volumes/vnode/_data:/var/www/tg/static

相关问题