Cas*_*ils 6 stdout stderr docker
我有以下 Dockerfile:
FROM ubuntu:16.04
RUN apt-get update
VOLUME ["/LOGS"]
COPY ./testServer .
ENTRYPOINT ./testServer 8600
Run Code Online (Sandbox Code Playgroud)
“testServer”具有正在写入的日志文件。它们位于目录“LOGS”中。每次启动“testServer”时,都会创建一个新日志。我想要做的是将目录中的最新日志文件“拖尾”到 stdout/stderr。
我尝试添加:
CMD ["/bin/sh", "-c", "tail $( ls -Art /LOGS | tail -n 1 ) > out_server.log 2>&1"]
Run Code Online (Sandbox Code Playgroud)
到 Dockerfile(并在此之后重建映像)但它不起作用。
如何才能做到这一点?
TIA
这里有两个问题。
您已经ENTRYPOINT定义了并且您正在尝试使用 运行命令CMD。Docker 使用单个进程启动一个容器,当您定义这两个进程时,CMD它会作为附加的 cli 参数附加到后面ENTRYPOINT。容器以 pid 1 运行的内容是:
/bin/sh -c './testServer 8600 /bin/sh -c "tail $( ls -Art /LOGS | tail -n 1 ) > out_server.log 2>&1"'
除非 testServer 运行额外的参数,否则它们永远不会被使用。
如果您运行的命令确实有效,它会将所有内容输出到容器内的 /out_server.log,而不是 stdout,并且一旦到达输入末尾,它就会停止。如果那是你的 pid 1,容器也会在此时退出。
要解决此问题,您可以创建一个如下所示的entrypoint.sh:
#!/bin/sh
./testServer 8600 &
sleep 2 # give testServer time to create the newest log
exec tail -f $( ls -Art /LOGS | tail -n 1 )
Run Code Online (Sandbox Code Playgroud)
该入口点在后台启动 testServer,然后使用 exec 运行 tail。exec 替换了 pid 1,以便信号通过。
将您的 Dockerfile 更新为:
FROM ubuntu:16.04
# This apt-get line shouldn't be needed unless something else
# needs the possibly outdated package repo list
# RUN apt-get update
# Removing this volume, you can create it from a docker-compose.yml
# VOLUME ["/LOGS"]
COPY entrypoint.sh testServer /
RUN chmod 755 /entrypoint.sh /testServer
ENTRYPOINT [ "/entrypoint.sh" ]
Run Code Online (Sandbox Code Playgroud)
有关为什么删除该VOLUME行的更多详细信息,请参阅我的博客文章此处。
小智 7
相反,您可以使用 tail 将日志文件符号链接到容器进程的标准输出。为此,您需要将可执行文件包装在一个单独的脚本中,以便它作为一个独立于容器主进程的进程启动。
要执行的脚本:
#!/bin/bash
# The application log will be redirected to the main docker container process's stdout, so # that it will show up in the container logs
touch /my/app/application.log
ln -sf /proc/1/fd/1 /my/app/application.log
# Execute my app
./testServer 8600
Run Code Online (Sandbox Code Playgroud)
并在 docker 文件中复制并执行脚本
COPY start_server.sh /the/above/script/start_server.sh
CMD ["/bin/bash", "/the/above/script/start_server.sh"]
Run Code Online (Sandbox Code Playgroud)
小智 5
我发现以下很有用。
#forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
Run Code Online (Sandbox Code Playgroud)
由于上述几行,写入access.log和 的内容error.log将分别写入stdout和stderr。
| 归档时间: |
|
| 查看次数: |
12239 次 |
| 最近记录: |