Docker容器中Ruby进程输出无法通过docker logs查看的原因及解决方法
Docker容器运行后
docker logs无输出?看这篇解决! 我遇到的问题:
我写了下面这个Dockerfile:
FROM ruby:2.4 CMD ruby -e "while true do; puts 'Hello, world!'; sleep 1; end"
执行docker run <image>启动容器后,用docker logs <container>查看日志,结果啥输出都没有。我的Docker版本是:
~$ docker --version Docker version 18.03.1-ce, build 9ee9f40
为啥会这样?
其实问题出在Ruby的输出缓冲机制上——Ruby的puts默认会把输出内容先缓冲起来,不会立刻写到标准输出(stdout)里。而Docker的日志是直接读取容器的stdout/stderr流的,缓冲没刷新的话,Docker自然拿不到内容,所以你查日志就啥也看不到。
怎么解决?
给你两个简单的解决思路,随便选一个都行:
方法一:让Ruby关闭输出缓冲
修改Ruby命令,加上-u参数(这个参数是让Ruby启用无缓冲模式),这样puts的内容会直接输出到stdout,不会再憋着。修改后的Dockerfile:FROM ruby:2.4 CMD ruby -u -e "while true do; puts 'Hello, world!'; sleep 1; end"方法二:把输出转到stderr(标准错误流)
如果你不想改Ruby的参数,也可以把输出内容写到stderr里——因为stderr默认是没有缓冲的,内容会立刻被Docker捕获。有两种写法:
第一种直接在Ruby代码里指定输出到stderr:FROM ruby:2.4 CMD ruby -e "while true do; $stderr.puts 'Hello, world!'; sleep 1; end"第二种用shell的重定向语法,把stdout转到stderr:
FROM ruby:2.4 CMD ruby -e "while true do; puts 'Hello, world!'; sleep 1; end" >&2
验证一下:
重新构建镜像:docker build -t ruby-hello .,然后后台运行容器docker run -d ruby-hello,过个几秒钟用docker logs <你的容器ID>查看,就能看到不断输出的Hello, world!啦!
内容的提问来源于stack exchange,提问作者zuba
相关产品推荐
相关产品推荐

