bash Docker:RUN touch 不创建文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41412807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 15:34:31  来源:igfitidea点击:

Docker: RUN touch doesn't create file

bashdockerdocker-composedockerfile

提问by Philippe Hebert

While trying to debug a RUN statements in my Dockerfile, I attempted to redirect output to a file in a bound volume (./mongo/log).

在尝试调试 Dockerfile 中的 RUN 语句时,我尝试将输出重定向到绑定卷 ( ./mongo/log) 中的文件。

To my surprise I was unable to create files via the RUN command, or to pipe the output of another command to a file using the redirection/appending (>,>>) operators. I was however able to perform the said task by logging in the running container via docker exec -ti mycontainer /bin/shand issuing the command from there.

令我惊讶的是,我无法通过 RUN 命令创建文件,也无法使用重定向/追加 ( >, >>) 运算符将另一个命令的输出通过管道传输到文件。但是,我能够通过登录正在运行的容器docker exec -ti mycontainer /bin/sh并从那里发出命令来执行上述任务。

Why is this behaviour happening? How can I touch file in the Dockerfile / redirect output to a file or to the console from which the Dockerfile is run?

为什么会发生这种行为?如何触摸 Dockerfile 中的文件/将输出重定向到文件或运行 Dockerfile 的控制台?

Here is my Dockerfile:

这是我的 Dockerfile:

FROM mongo:3.4

#Installing NodeJS
  RUN apt-get update && \
    apt-get install -y curl && \
    curl -sL https://deb.nodesource.com/setup_6.x | bash - && \
    apt-get install -y nodejs


#Setting Up Mongo
  WORKDIR /var/www/smq
  COPY ./mongo-setup.js mongo-setup.js

  ##for testing
  RUN touch /var/log/node.log && /
      node --help 2>&1 > /var/log/node.log

  ##this was the command to debug
  #RUN node mongo-setup.js > /var/log/mongo-setup.log 2> /var/log/mongo-setup.error.log

Here an excerpt from my docker-compose.yml:

这是我的 docker-compose.yml 的摘录:

mongodb:
    build:
      context: ./
      dockerfile: ./mongodb-dockerfile
    container_name: smqmongodb
    volumes:
     - /var/lib/mongodb/data
     - ./mongo/log/:/var/log/
     - ../.config:/var/www/.config

采纳答案by Socratees Samipillai

Instead of RUN node mongo-setup.js > /var/log/mongo-setup.log 2> /var/log/mongo-setup.error.log, within the container, what if you just say `RUN node mongo-setup.js'?

而不是RUN node mongo-setup.js > /var/log/mongo-setup.log 2> /var/log/mongo-setup.error.log在容器内,如果您只说“运行节点 mongo-setup.js”会怎样?

Docker recommends using docker logs. Like so:

Docker 建议使用docker logs. 像这样:

docker logs container-name

To accomplish what you're after (see the mongo setup logs?), you can split the stdout & stderr of the container by piping the separate streams: and send them to files:

为了完成您所追求的事情(请参阅 mongo 设置日志?),您可以通过管道传输单独的流来拆分容器的 stdout 和 stderr: 并将它们发送到文件:

me@host~$ docker logs foo > stdout.log 2>stderr.log

me@host~$ cat stdout.log
me@host~$ cat stderr.log

Also, refer to the docker logs documentation

另外,请参阅docker 日志文档

回答by Dan Lowe

You are doing this during your build:

您在构建期间执行此操作:

RUN touch /var/log/node.log && /
    node --help 2>&1 > /var/log/node.log

The file /var/log/node.logis created and fixed immutably into the resulting image.

该文件/var/log/node.log被创建并固定不变地固定到生成的图像中。

Then you run the container with this volume mount:

然后使用此卷挂载运行容器:

volumes:
  - ./mongo/log/:/var/log/

Whatever is in ./mongo/log/is mounted as /var/login the container, which hides whatever was there before (from the image). This is the thing that's making it look like your touchdidn't work (even though it probably worked fine).

无论是在./mongo/log/被安装作为/var/log在容器中,(从图像)之前,其兽皮无论在那里。这就是让它看起来像你touch没有工作的事情(即使它可能工作正常)。

You're thinking about this backward - your volume mount doesn't expose the container's version of /var/logexternally - it replaces whatever was there.

您正在向后考虑这个问题-您的卷安装不会在/var/log外部公开容器的版本-它会替换那里的任何内容。

Nothing you do in Dockerfile (build) will ever show up in an external mount.

您在 Dockerfile (build) 中所做的任何事情都不会出现在外部挂载中。