在完成运行后检查非守护程序Docker容器

我有一个我创build的容器

# start docker build -t cdt-tests . docker run -it --name cdt-tests cdt-tests # end => I want to inspect the container filesystem after it's done 

因为它没有运行在分离模式下,我怎么检查容器? 我想做的是防止容器“自动closures”,以便在容器完成后检查容器的文件系统。

Dockerfile cdt-tests看起来像:

 FROM node:6 RUN apt-get update && \ apt-get -y install sudo RUN sudo apt-get -y update RUN sudo apt-get -y upgrade RUN sudo apt-get install -y sqlite3 libsqlite3-dev USER root RUN mkdir -p /tmp/test-deps RUN mkdir -p /usr/local/cdt-tests WORKDIR /usr/local/cdt-tests ENV SUMAN_POSTINSTALL_IS_DAEMON no RUN rm -rf node_modules RUN npm set progress=false RUN npm config set loglevel=warn RUN npm set loglevel=warn COPY package.json . RUN npm install --no-optional > /dev/null 2>&1 RUN npm install bower > /dev/null 2>&1 COPY . . RUN ./node_modules/.bin/bower install --config.interactive=false --allow-root > /dev/null 2>&1 ENTRYPOINT ["/bin/bash", "/usr/local/cdt-tests/@run-tests.sh"] 

我知道使用的技巧来覆盖入口点,并检查容器,如下所示:

 docker run -it --entrypoint /bin/bash --name cdt-tests cdt-tests 

但是,这对我目前的用例来说不起作用,因为我想 @ run-tests.sh完成之后检查容器!

所以我有两个问题:

  1. 在完成运行后,如何检查非守护程序容器的文件系统?
  2. 我如何获取为非守护程序容器创build的容器的容器标识(不使用$(docker ps))。

如果我做一个docker ps -a ,我会看到:

 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 08740a432d1c cdt-tests "/bin/bash /usr/lo..." 24 seconds ago Exited (130) 7 seconds ago cdt-tests f27a302b1d8f cdt-server "/bin/bash /usr/lo..." 38 seconds ago Up 36 seconds cdt-server b854506e75df cisco-selenium "/opt/bin/entry_po..." 41 seconds ago Up 39 seconds 4444/tcp cdt-selenium a37cab33b293 mongo "docker-entrypoint..." 43 seconds ago Up 41 seconds 27017/tcp cdt-mongo 

所以我们可以看到cdt-tests在那里,即使它不是守护进程。

所以我们试图检查它,像这样:

 docker exec cdt-tests /bin/bash 

但是我们得到一个错误:

 Error response from daemon: Container 08740a432d1c8f014bc138c82706de1e9682a052c088531d60b33c6acbbd5559 is not running 

该怎么办?

在完成运行后,如何检查非守护程序容器的文件系统?

使用docker cp 。 看文档

docker cp实用程序将SRC_PATH的内容复制到DEST_PATH。 您可以从容器的文件系统复制到本地机器,或者从本地文件系统复制到容器。 (…)容器可以是运行或停止的容器。 SRC_PATH或DEST_PATH可以是文件或目录。

另一种select是实现您的容器到一个新的形象,并在其上运行:

 docker commit <stopped-container> new_image_name docker run -it --entrypoint /bin/bash new_image_name 

我如何获取为非守护程序容器创build的容器的容器标识(不使用$(docker ps))。

1)当你做docker run -d输出是已经创build的容器ID,所以你可以保存该信息:

 container_id=$(docker run -d .......) 

2)这将显示停止的testing容器:

 docker ps -a --filter ancestor=cdt-tests 

并把这个放入最后一个停止的testing容器中:

 container_id=$(docker ps -q -a --filter ancestor=cdt-tests | head -n1) 

每种情况下还有许多其他变体。


编辑。 使用卷版本方法,您可以将单个文件绑定为卷:

 docker run -v ./tests.log:/path/to/logs/file.log -it --name cdt-tests cdt-tests 

我不知道问题2.但对于问题1,一个可能的解决scheme是陷阱退出信号 – 虽然这将在容器内部执行。 但是,我猜如果目标是检查容器中的文件系统,您可以将结果传输到挂载的目录。

例如在run-tests.sh脚本中添加

 exiting() { # do file system inspection here } # trap the exit signal trap exiting SIGINT SIGTERM EXIT 

编辑:要将日志目录/文件挂载到主机,请使用-v选项,

 docker run -it -v $HOME/log:/var/log --name cdt-tests cdt-tests 

注意,当使用-v选项时,确保你没有装载到容器的工作目录 – docker会用主机内容覆盖它。

docker cp命令上的其他答案也应该起作用。 我主要使用-v,因为在主机上存在日志意味着我有可能在程序运行时使用tail -f来检查或观察它。 这取决于用例。 另外要记住的是,如果程序运行正常,容器将无错误地退出,并且不能复制。 容器只有在出错时才会停留。