无法从另一个容器访问docker容器创建的文件?

无法从另一个容器访问docker容器创建的文件?,r,docker,shiny,containers,devops,R,Docker,Shiny,Containers,Devops,对于当前的工作场景,我有两个需要共享数据的容器。第一个容器是一个flask应用程序,它对数据进行一些处理并创建日志文件。另一个容器是R Shining app,它充当应用程序的状态仪表板,并且在需要时,用户还可以通过在仪表板上提供一个键来直接查看日志文件。这里我的问题是,当从Shining dashboard容器访问日志文件时,会抛出“权限被拒绝”错误。我在这两个容器上安装了相同的卷,也尝试向所有者授予Shining app容器的权限,但容器仍然无法访问该文件,而我可以访问主机位置上的相同文件。

对于当前的工作场景,我有两个需要共享数据的容器。第一个容器是一个flask应用程序,它对数据进行一些处理并创建日志文件。另一个容器是R Shining app,它充当应用程序的状态仪表板,并且在需要时,用户还可以通过在仪表板上提供一个键来直接查看日志文件。这里我的问题是,当从Shining dashboard容器访问日志文件时,会抛出“权限被拒绝”错误。我在这两个容器上安装了相同的卷,也尝试向所有者授予Shining app容器的权限,但容器仍然无法访问该文件,而我可以访问主机位置上的相同文件。我是否缺少需要容器间共享卷授权的内容,或者Shining应用程序是否存在任何问题。请提供可能的解决方案

必需文件 Docker编写文件。 Docker为应用程序编写文件:

version: '3.7'
services:
  app:
    container_name: app
    image: mlengine
    networks:
      - network1
    build:
      context: .
      dockerfile: DockerfileEngine
    volumes:
      - ./logs_n_status:/root/project/logs_n_status
      #- logData:/root/project/logs_n_status
    ports:
      - 7011:3000
    expose:
      - "3000"
闪亮仪表板的Docker compose文件:

# docker-compose.yml
version: '3.7'
services:
  dashboard:
    container_name: dashboard
    image: mlapidashboard
    networks:
      - network1
    build:
      context: .
      dockerfile: DockerfileRTD
    volumes:
      - /home/mlprod/dmda/testAPI/logs_n_status:/root/project/logs_n_status
      #--volumes-from Container4:ro
      #- logData:/root/project/logs_n_status:ro
    ports:
      - 9000:3838
networks:
    network1:
#volumes:
#    logData:
DockerfileEngine:

FROM ubuntu:18.04
RUN apt-get --fix-missing update && apt-get --fix-broken install && apt-get install -y poppler-utils && apt-get install -y tesseract-ocr && \
    apt-get install -y libtesseract-dev && apt-get install -y libleptonica-dev && ldconfig && apt-get install -y python3.6 && \
    apt-get install -y python3-pip && apt install -y libsm6 libxext6

RUN apt-get update && \
    apt-get install -y openjdk-8-jdk && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    rm -rf /var/cache/oracle-jdk8-installer;

ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/
RUN export JAVA_HOME

WORKDIR /root/
RUN mkdir /root/project
WORKDIR /root/project
RUN mkdir /root/project/processingDirectory

ADD requirements.txt .
RUN pip3 install -r ./requirements.txt

COPY ./xxxx xxxx

RUN python3 ./nltkDownloader.py
CMD ["gunicorn", "-t", "999999", "--bind", "0.0.0.0:3000", "wsgi:app"]
DockerfileDashboard:

FROM rocker/shiny:3.5.1

RUN apt-get update && apt-get install libcurl4-openssl-dev libv8-3.14-dev libsasl2-dev libssl-dev -y &&\
  mkdir -p /var/lib/shiny-server/bookmarks/shiny

RUN R -e "install.packages(c('mongolite', 'dplyr', 'jsonlite', 'ggplot2', 'grid', 'gridExtra', 'DT', 'data.table', 'httr', 'shiny'))"

RUN mkdir /root/project
RUN mkdir /root/project/logs_n_status

COPY ./RealTimeDashboard /srv/shiny-server/RealTimeDashboard

RUN chmod -R 755 /srv/shiny-server/
RUN chmod -R 777 /root/project/logs_n_status

EXPOSE 3838

CMD ["/usr/bin/shiny-server.sh"]

问题是
rocker/shinny
shinny
用作用户(),而另一个应用程序使用
root
生成日志(他们可能设置了特权)

该用户的UID=999。 如何提取它:

$ docker run -it --rm rocker/shiny bash
root@536f2edc5768:/usr/bin# su - shiny
$ id
uid=999(shiny) gid=999(shiny) groups=999(shiny)
为了解决您的问题,我将DockerfileEngine更改为如下所示:

FROM ubuntu:18.04
RUN apt-get --fix-missing update && apt-get --fix-broken install && apt-get install -y poppler-utils && apt-get install -y tesseract-ocr && \
    apt-get install -y libtesseract-dev && apt-get install -y libleptonica-dev && ldconfig && apt-get install -y python3.6 && \
    apt-get install -y python3-pip && apt install -y libsm6 libxext6

RUN apt-get update && \
    apt-get install -y openjdk-8-jdk && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    rm -rf /var/cache/oracle-jdk8-installer;

RUN useradd -ms /bin/bash -u 999 theuser
RUN mkdir -p /project \
    && chown -R theuser /project

USER theuser
WORKDIR /project

ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/
RUN export JAVA_HOME

RUN mkdir /project/processingDirectory

ADD requirements.txt .
RUN pip3 install -r ./requirements.txt

COPY --chown=theuser ./xxxx xxxx

RUN python3 ./nltkDownloader.py
CMD ["gunicorn", "-t", "999999", "--bind", "0.0.0.0:3000", "wsgi:app"]

确保装载的文件夹可由两个容器写入。

如何启动这些容器?您还可以共享docker文件吗?请给出最少的示例。@Stefano我已经添加了docker compose文件(仅是必需的部分),并且没有使用仪表板的docker compose文件,而是使用docker run命令来启动container@atline请考虑EdtSCAN添加DoCKFr档的部分内容吗?比如你使用的是什么基本图像,你是否更改了其中的用户等等?谢谢你的回答@Stefano。我很好奇,我们是否可以完全颠倒相同的过程,或者不使用
rocker/shinny
基本映像,而是在ubuntu映像本身上安装shinny服务器。这样做的积极或消极后果可能是什么。您可以使用root重写shiny-server.sh的内容,但我不确定它是否有效,而且这始终是一个安全问题。“DockerfileEngine”图像也是如此。使用root-in从来都不是一个好主意(当涉及到安全性时)。关于在主机上使用shiny的想法,我被迫使用类似的设置,这一点都不有趣(特别是如果您计划在容器和主机之间进行通信),在构建映像和运行容器时,我遇到以下错误。错误出现在我创建新用户的主应用程序中<代码>错误:for app无法启动服务app:OCI运行时创建失败:container\u linux.go:345:启动容器进程导致“exec:\“gunicorn\”:在$PATH中找不到可执行文件:未知错误:启动项目时遇到错误尝试使用
docker run--user root-it--rm$imageName bash
进入容器,检查
gunicorn
路径并修复cmdThank@Stefano,仪表板容器现在能够读取应用程序容器创建的数据。问题已经解决