在docker中redirect命令输出

我想为我的服务器做一些简单的日志logging,这是一个在Docker容器中运行的小型Flask应用程序。

这是Dockerfile

# Dockerfile FROM dreen/flask MAINTAINER dreen WORKDIR /srv # Get source RUN mkdir -p /srv COPY perfektimprezy.tar.gz /srv/perfektimprezy.tar.gz RUN tar x -f perfektimprezy.tar.gz RUN rm perfektimprezy.tar.gz # Run server EXPOSE 80 CMD ["python", "index.py", "1>server.log", "2>server.log"] 

正如你在最后一行所看到的,我将stderr和stdoutredirect到一个文件。 现在我运行这个容器和shell

 docker run -d -p 80:80 perfektimprezy docker exec -it "... id of container ..." bash 

并观察以下几点:

服务器正在运行,网站正在运行

没有/srv/server.log

ps aux | grep python ps aux | grep python yield:

 root 1 1.6 3.2 54172 16240 ? Ss 13:43 0:00 python index.py 1>server.log 2>server.log root 12 1.9 3.3 130388 16740 ? Sl 13:43 0:00 /usr/bin/python index.py 1>server.log 2>server.log root 32 0.0 0.0 8860 388 ? R+ 13:43 0:00 grep --color=auto python 

但是,没有日志…但是,如果我docker attach到容器,我可以看到在控制台中生成输出的应用程序。

在使用Docker时,如何正确地将stdout / errredirect到文件?

Dockerfile JSON列表指定为CMD时,它不会在shell中执行,所以通常的shell函数(如stdout和stderr重定向)将不起作用。

从文档 :

exec表单被解析为一个JSON数组,这意味着你必须在单词中使用双引号( " )而不是单引号( ' )。

与shell形式不同,exec形式不会调用命令shell。 这意味着正常的shell处理不会发生。 例如, CMD [ "echo", "$HOME" ]不会在$HOME上进行变量替换。 如果你想要shell处理,那么要么使用shell的形式,要么直接执行一个shell,例如: CMD [ "sh", "-c", "echo", "$HOME" ]

你的命令实际上执行的是执行你的index.py脚本,并将字符串"1>server.log""2>server.log"作为命令行参数传递给该python脚本

使用下面的其中一个代替(都应该工作):

  1. CMD "python index.py > server.log 2>&1"
  2. CMD ["/bin/sh", "-c", "python index.py > server.log 2>&1"]

作为补充,当使用docker-compose时 ,你也可以尝试:

command: bash -c "script_or_command > /path/to/log/command.log 2>&1"