Docker CMD末尾的tail -f输出没有显示

使用Docker for Mac 1.13.1和以下Dockerfile:

FROM ubuntu:latest MAINTAINER docker@ekito.fr #Install packages and clean downloaded packages in the lowest layer RUN apt-get update && apt-get -y install cron && rm -rf /var/lib/apt/lists/* # Add crontab file in the cron directory ADD crontab /etc/cron.d/hello-cron # Give execution rights on the cron job and create the log file to tail in the next layer RUN chmod 0644 /etc/cron.d/hello-cron && touch /var/log/cron.log # Run the command on container startup CMD echo "starting" && echo "continuing" && (cron) && echo "tailing..." && tail -f /var/log/cron.log 

有一个contab文件:

 * * * * * root echo "Hello world `date`" >> /var/log/cron.log 2>&1 # Don't remove the empty line at the end of this file. It is required to run the cron job 

当我build立并运行它时:

 docker build -t docker-cron-master . docker run docker-cron-master 

我看到输出:

 docker run docker-cron-master starting continuing tailing... 

如果我等一会儿tail -f输出不出现。 但是,如果我login到正在运行的容器并尾部文件,我可以看到的内容:

 $ docker exec -it 4eda6b1fc6ce bash root@4eda6b1fc6ce:/# tail -f /var/log/cron.log Hello world Fri May 5 09:53:01 UTC 2017 Hello world Fri May 5 09:54:01 UTC 2017 

我试图在CMD的末尾添加另一个回显,看是否只有最后一个被STDOUT吞咽的命令,但没有帮助。

我已经发布了代码在https://github.com/simbo1905/docker-cron的 github上

谢谢!

docker文件系统使用copy-on-write和分层联合fs。 所以,当你写一个文件作为图像的一部分的时候,它会首先把这个文件复制到容器文件系统,这个文件系统是所有图像层之上的一个图层。

这意味着当你在/var/log/cron.log中添加一行时,它会在文件系统中获得一个新的inode,而tail命令所在的文件不再是你在docker exec时看到的文件进入容器。 你可以通过一个小的修改来解决这个问题:在文件中追加“nothing”,这个文件也修改了最后一个更新时间戳,这个时间戳强制写时复制:

 CMD echo "starting" && echo "continuing" && (cron) \ && echo "tailing..." && : >> /var/log/cron.log && tail -f /var/log/cron.log