我想为我的服务器做一些简单的日志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脚本 。
使用下面的其中一个代替(都应该工作):
CMD "python index.py > server.log 2>&1"
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"