我想对我的服务器进行一些简单的日志记录,我的服务器是一个在 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 和 stdout 重定向到一个文件。现在我运行这个容器并将 shell 放入其中
docker run -d -p 80:80 perfektimprezy
docker exec -it "... id of container ..." bash
并观察以下几点:
服务器正在运行,网站正常运行
没有/srv/server.log
ps aux | grep python
产量:
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/err 重定向到文件?
答案1
我想问一下你的用例。为什么你需要将 stderr/stdout 重定向到容器中的日志文件?合并的 stderr 和 stdout 可在容器外部使用“docker logs”,并且可以重定向到文件(容器外部)。更多详细信息请参见这里
答案2
以下是相关用例的一些信息:您想要重定向在 Docker Cloud 上运行的容器内的输出。
就我而言,我在 Docker Cloud 上执行一个长时间运行的数据分析脚本(Java)。每个容器都应该编写自己的结果文件。我正在使用镜像java:8-jre
并用以下行覆盖“运行命令”:
bash -c "java -jar /code/analyzer.jar > /data/results-$RANDOM.txt"
通过使用 bash 的$RANDOM
变量,我可以根据需要扩大 Docker Cloud 中的容器数量,同时仍然单独收集结果。
答案3
您正在寻找 T 恤
LOGFILE="logthis.txt";
IMG_alpine="alpine:3.5";
docker run --rm \
--name alpine-hello \
--hostname alpine-hello \
"$IMG_alpine" \
uname -a | tee -a $LOGFILE
cat logthis.txt
Linux alpine-hello 4.8.14-docker-2 #1 SMP Tue Jan 10 15:35:02 UTC 2017 x86_64 Linux
答案4
docker run
要在 shell 管道中或 shell 重定向下使用,使其run
接受 stdin 并适当地输出到 stdout 和 stderr,请使用以下咒语:
docker run -i --log-driver=none -a stdin -a stdout -a stderr ...
例如,运行映像并在包含的环境中alpine
执行 UNIX 命令:cat
echo "This was piped into docker" |
docker run -i --log-driver=none -a stdin -a stdout -a stderr \
alpine cat - |
xargs echo This is coming out of docker:
发出:
This is coming out of docker: This was piped into docker