如何在两个docker容器之间共享一个文件夹内容,并允许其中一个删除并写入共享文件夹?

时间:2020-02-03 13:09:57

标签: docker docker-compose

我正在使用docker为ionic / Angluar项目创建开发环境。其中Node.js是用于从主机上的src代码(本地src代码)(带有www)监视和构建ng build --watch --poll=2000文件的映像,而NGINX映像应获取生成的www文件夹。 / p>

针对此用例,我尝试了两种方法,但均失败了:

  • 方法1:我已将文件夹绑定安装到两个容器:这里的问题是NGINX容器无法从主机上的www同步/获取文件。虽然,NodeJS容器设法生成文件并与主机目录www同步。原因是:当NODEJS删除并重新生成www目录时,NGINX释放绑定安装。
  • 方法2:我已经使用了数据量:但是NodeJS容器在启动时失败,因为它无法删除此www文件以便用新的www子文件重新生成(因为它已被锁定) NGINX)。 错误消息:
frontend        | EBUSY: resource busy or locked, rmdir '/home/frontend/www'
frontend        | Error: EBUSY: resource busy or locked, rmdir '/home/frontend/www'
frontend        |     at Object.rmdirSync (fs.js:752:3)
...

撰写文件的外观如下:(我在撰写文件中标记了上述方法,但是我一次只使用了一次)

version: "3.7"

services:
  web-server:
    image: webserver-nginx:latest
    container_name: webserver
    build:
      context: ../nginx/
      dockerfile: Dockerfile-nginx    
    ports:
    - "80:80"
    volumes:
    - /my_host_machine/www:/usr/share/nginx/html:ro # approach number 1
    - www:/usr/share/nginx/html/afv:ro # approach number 2
    depends_on:
      - frontend

  frontend:
    image: frontend-angular:latest
    container_name: frontend
    build:
      context: /foo/
      dockerfile: Dockerfile-nodejs-frontend
    volumes:
      - /my_host_machine/www:/home/frontend/www # approach number 1
      - www:/home/frontend/www # approach number 2

volumes:
  www:

有人可以帮我吗,或者有建议或解决方法?

2 个答案:

答案 0 :(得分:0)

我认为您的第一个选择几乎是可行的。尝试获取该绑定的安装目录,并在其中创建www的子目录,并在其中创建源目录的子目录。从源目录构建一个容器,然后将结果移至www目录,其他容器将在该目录中将其拾取(不删除整个目录)。

答案 1 :(得分:0)

事实证明问题出在以下方面:

我使用了方法#1

此问题仅在初始化时发生,在初始化点,NGINX对其保持绑定安装后,NODEJS删除了www文件夹。 在NODEJS完成生成www文件夹和文件之后,重新启动NGINX容器将解决该问题,即使NODEJS之后又重新生成了网络文件(因为它不会再次删除完整的文件夹)。

我使用了HealthCheck和自动修复容器,而不是每次都手动重新启动NGINX。 (请注意,如果您使用的是群集,则不需要自动修复容器)

这是我的做法:

创建healthcheck.sh,其中Dockerfile是:

#!/bin/bash
if [ -z "$(ls -A /path/to/mounted/file/in/NGINX/container)" ]; then exit 1; else exit 0; fi

将这些行添加到NGINX Dockerfile:

COPY healthcheck.sh .

HEALTHCHECK --interval=3s --retries=10 CMD sh /healthcheck.sh

将这些行添加到docker-compose.yml:

autoheal:
image: willfarrell/autoheal
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
  AUTOHEAL_CONTAINER_LABEL: all
restart: always