简体   繁体   English

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

[英]Docker - Can't share data between containers within a volume (docker-compose 3)

I have some containers for a web app for now (nginx, gunicorn, postgres and node to build static files from source and a React server side rendering).我现在有一些用于 Web 应用程序的容器(nginx、gunicorn、postgres 和节点,用于从源代码和 React 服务器端渲染构建静态文件)。 In a Dockerfile for the node container I have two steps: build and run ( Dockerfile.node ).在节点容器的 Dockerfile 中,我有两个步骤:构建和运行( Dockerfile.node )。 It ends up with two directories inside a container: bundle_client - is a static for an nginx and bundle_server - it used in the node container itself to start an express server.它最终在容器内有两个目录: bundle_client - 是 nginx 和bundle_server的静态bundle_server - 它在节点容器本身中用于启动快速服务器。

Then I need to share a built static folder ( bundle_client ) with the nginx container.然后我需要与 nginx 容器共享一个内置的静态文件夹( bundle_client )。 To do so according to docker-compose reference in my docker-compose.yml I have the following services (See full docker-compose.yml ):为此,根据我docker-compose.yml -compose 参考,我有以下服务(请参阅完整的 docker-compose.yml ):

node:
  volumes:
    - vnode:/usr/src

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

and volumes:和卷:

volumes:
  vnode:

Running docker-compose build completes with no errors.运行docker-compose build完成,没有错误。 Running docker-compose up runs everyting ok and I can open localhost:80 and there is nginx, gunicorn and node express SSR all working great and I can see a web page but all static files return 404 not found error.运行docker-compose up运行一切正常,我可以打开localhost:80并且有 nginx、gunicorn 和 node express SSR 都运行良好,我可以看到一个网页,但所有静态文件都返回 404 not found 错误。

If I check volumes with docker volume ls I can see two newly created volumes named tg_vnode (that we consider here) and tg_vdata (see full docker-compose.yml)如果我使用docker volume ls检查卷,我可以看到两个新创建的卷,名为tg_vnode (我们在这里考虑)和tg_vdata (请参阅完整的 docker-compose.yml)

If I go into an nginx container with docker run -ti -v /tmp:/tmp tg_node /bin/bash I can't see my www/tg/static folder which should map my static files from the node volume.如果我使用docker run -ti -v /tmp:/tmp tg_node /bin/bash进入 nginx 容器,我将看不到我的www/tg/static文件夹,该文件夹应该从节点卷映射我的静态文件。 Also I tried to create an empty /var/www/tg/static folder with nginx container Dockerfile.nginx but it stays empty.此外,我尝试使用 nginx 容器Dockerfile.nginx创建一个空的/var/www/tg/static文件夹,但它保持为空。

If I map a bundle_client folder from the host machine in the docker-compose.yml in a nginx.volumes section as - ./client/bundle_client:/var/www/tg/static it works ok and I can see all the static files served with nginx in the browser.如果我在nginx.volumes部分的nginx.volumes docker-compose.yml中将bundle_client文件夹从主机映射为- ./client/bundle_client:/var/www/tg/static它工作正常,我可以看到所有静态文件在浏览器中与 nginx 一起提供。

What I'm doing wrong and how to make my container to share built static content with the nginx container?我做错了什么以及如何让我的容器与 nginx 容器共享构建的静态内容?

PS: I read all the docs, all the github issues and stackoverflow Q&As and as I understood it has to work and there is no info what to do when is does not. PS:我阅读了所有文档、所有 github 问题和 stackoverflow 问答,据我所知,它必须可以工作,但没有信息可以在不工作时做什么。

UPD: Result of docker volume inspect vnode : 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"
}
]

Files: Dockerfile.node , docker-compose.yml文件: Dockerfile.nodedocker-compose.yml

Nginx dockerfile:Dockerfile.nginx Nginx dockerfile:Dockerfile.nginx


UPD: I have created a simplified repo to reproduce a question: repo (there are some warnings on npm install nevermind it installs and builds ok). UPD:我创建了一个简化的 repo 来重现一个问题: reponpm install上有一些警告,不管它安装和构建是否正常)。 Eventually when we open localhost:80 we see an empty page and 404 messages for static files ( vendor.js and app.js ) in Chrome dev tools but there should be a message React app: static loaded generated by react script.最终,当我们打开localhost:80时,我们会在 Chrome 开发工具中看到一个空页面和静态文件( vendor.jsapp.js )的 404 消息,但应该有一条消息React app: static loaded由 react 脚本生成的React app: static loaded

Two changes you need.你需要两个改变。 In your node service add the volume like:在您的节点服务中添加如下卷:

volumes:
  - vnode:/usr/src/bundle_client

Since you want to share /usr/src/bundle_client you should NOT be using /usr/src/ because that will share the full folder and the structure too.因为你想共享/usr/src/bundle_client你不应该使用/usr/src/因为这也将共享完整的文件夹和结构。

And then in your nginx service add the volume like:然后在您的 nginx 服务中添加如下卷:

volumes:
  - type: volume
    source: vnode
    target: /var/www/test/static
    volume:
      nocopy: true

The nocopy: true keeps our intention clear that on initial map of the container the content of the mapped folder should not be copied. nocopy: true明确了我们的意图,即在容器的初始映射上,不应复制映射文件夹的内容。 And by default the first container to get mapped to the volume will get the contents of the mapped folder.默认情况下,第一个映射到卷的容器将获取映射文件夹的内容。 In your case you want this to be the node container.在您的情况下,您希望这是node容器。

Also before testing make sure you run below command to kill the cached volumes:同样在测试之前,请确保您运行以下命令来终止缓存的卷:

docker-compose down -v

You can see during my test the container had the files:您可以在我的测试期间看到容器中包含以下文件:

Nginx 有文件

Explanation of what happens step by step逐步解释发生的事情

Dockerfile.node Dockerfile.node

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

docker-compose.yml docker-compose.yml

services:
  ...
  node:
    ...
    volumes:
      - ./server/nginx.conf:/etc/nginx/nginx.conf:ro
      - vnode:/usr/src
  ...
volumes:
  vnode:
  1. docker-compose up creates with this Dockerfile.node and docker-compose section a named volume with data saved in /usr/src. docker docker-compose up使用这个 Dockerfile.node 和 docker-compose 部分创建一个命名卷,数据保存在 /usr/src 中。

Dockerfile.nginx 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. That produces that nginx containers created with docker-compose will have an empty /var/www/tg/static/这会产生使用docker-compose创建的 nginx 容器将有一个空的/var/www/tg/static/

docker-compose.yml docker-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 will produce that vnode named volume is created and filled with data from /var/www/tg/static (empty by now) to existing vnode. docker-compose up将创建名为 volume 的vnode并填充来自/var/www/tg/static (现在为空)到现有 vnode 的数据。

So, at this point, - nginx container has /var/www/tg/static empty because it was created empty (see mkdir in Dockerfile.nginx) - node container has /usr/src dir with client file (see that was copied in Dockerfile.node) - vnode has content of /usr/src from node and /var/www/tg/static from nginx.所以,在这一点上, - nginx 容器有 /var/www/tg/static 空,因为它被创建为空(见 Dockerfile.nginx 中的 mkdir) - 节点容器有 /usr/src 目录和客户端文件(见复制Dockerfile.node) - vnode 具有来自node的 /usr/src 和来自 nginx 的/var/www/tg/static

Definitively, to pass data from /usr/src from your node container to /var/www/tg/static in nginx container you need to do something that is not very pretty because Docker hasn't developed another way yet: You need to combine named volume in source folder with bind volume in destination:明确地说,要将数据从node容器中的 /usr/src 传递到nginx容器中的/var/www/tg/static ,您需要做一些不太漂亮的事情,因为 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

Just change in docker-compose - vnode:/var/www/tg/static by - /var/lib/docker/volumes/vnode/_data:/var/www/tg/static只需在 docker-compose - vnode:/var/www/tg/static更改- /var/lib/docker/volumes/vnode/_data:/var/www/tg/static

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM