如何使用不同的命令启动已停止的Docker容器?

问题描述 投票:167回答:8

我想用一个不同的命令启动一个停止的Docker容器,因为默认命令崩溃 - 意味着我无法启动容器然后使用'docker exec'。

基本上我想启动一个shell,以便我可以检查容器的内容。

幸运的是我用-it选项创建了容器!

docker
8个回答
269
投票

Find your stopped container id

docker ps -a

Commit the stopped container:

此命令将修改后的容器状态保存到新图像user/test_image

docker commit $CONTAINER_ID user/test_image

Start/run with a different entry point:

docker run -ti --entrypoint=sh user/test_image

入口点参数描述:https://docs.docker.com/engine/reference/run/#/entrypoint-default-command-to-execute-at-runtime

Note:

上面的步骤只是启动具有相同文件系统状态的已停止容器。这对于快速调查非常有用。但是环境变量,网络配置,附加卷和其他人员不是继承的,您应该明确指定所有这些参数。

从这里借来了启动已停止容器的步骤:(最后评论)https://github.com/docker/docker/issues/18078


97
投票

编辑此文件(对应于已停止的容器):

vi /var/lib/docker/containers/923...4f6/config.json

更改“Path”参数以指向新命令,例如/斌/庆典。您还可以设置“Args”参数以将参数传递给命令。

重启docker服务(注意这将停止所有正在运行的容器):

service docker restart

列出容器并确保命令已更改:

docker ps -a

启动容器并连接到它,你现在应该在你的shell中!

docker start -ai mad_brattain

使用Docker 1.7.1在Fedora 22上工作。

注意:如果您的shell不是交互式的(例如,您没有使用-it选项创建原始容器),则可以将命令更改为“/ bin / sleep 600”或“/ bin / tail -f / dev / null”给你足够的时间做“docker exec -it CONTID / bin / bash”作为获取shell的另一种方式。

注意2:较新版本的docker有config.v2.json,您需要更改Entrypoint或Cmd(感谢user60561)。


13
投票

Add a check to the top of your Entrypoint script

Docker确实需要将其作为一项新功能实现,但这是另一种解决方法选项,用于在成功或失败后终止Entrypoint的情况,这会使调试变得困难。

如果您还没有Entrypoint脚本,请创建一个运行容器所需命令的脚本。然后,在此文件的顶部,将这些行添加到entrypoint.sh

# Run once, hold otherwise
if [ -f "already_ran" ]; then
    echo "Already ran the Entrypoint once. Holding indefinitely for debugging."
    cat
fi
touch already_ran

# Do your main things down here

为确保cat保持连接,您可能需要提供TTY。我正在使用我的Entrypoint脚本运行容器,如下所示:

docker run -t --entrypoint entrypoint.sh image_name

这将导致脚本运行一次,创建一个指示它已经运行的文件(在容器的虚拟文件系统中)。然后,您可以重新启动容器以执行调试:

docker start container_name

当您重新启动容器时,将找到already_ran文件,导致Entrypoint脚本停止使用cat(它将永远等待永远不会出现的输入,但保持容器处于活动状态)。然后,您可以执行调试bash会话:

docker exec -i container_name bash

当容器正在运行时,您还可以删除already_ran并手动执行entrypoint.sh脚本以重新运行它,如果您需要以这种方式进行调试。


1
投票

我接受了@Dmitriusan的答案并将其变成了别名:

别名docker-run-prev-container ='prev_container_id =“$(docker ps -aq | head -n1)”&& docker commit“$ prev_container_id”“prev_container / $ prev_container_id”&& docker run -it --entrypoint = bash“prev_container / $ prev_container_id“”

将其添加到您的~/.bashrc别名文件中,您将拥有一个漂亮的新docker-run-prev-container别名,它将您放入上一个容器中的shell。

有助于调试失败的docker builds。


1
投票

我的问题:

  • 我用docker run <IMAGE_NAME>开了一个容器
  • 然后将一些文件添加到此容器中
  • 然后我关闭容器并尝试使用与上面相同的命令再次启动它。
  • 但是当我检查新文件时,它们就丢失了
  • 当我运行docker ps -a时,我可以看到两个容器。
  • 这意味着每次我运行docker run <IMAGE_NAME>命令时,都会创建新图像

解决方案:要在首先运行的同一个容器上运行,请按照以下步骤操作

  • docker ps获取容器的容器
  • docker container start <CONTAINER_ID>启动现有容器
  • 然后你可以从你离开的地方继续。例如docker exec -it <CONTAINER_ID> /bin/bash
  • 然后,您可以决定从中创建新图像

0
投票

没有指定容器是否正在退出,只是您的代码崩溃了,您需要查看容器中发生了什么。如果它没有退出,这是另一个潜在的解决方案。

使用docker ps获取容器ID

docker exec -it 665b4a1e17b6 /bin/sh

如果将入口点设置为有问题的东西,也可以按照Dmitriusan的回答中的建议覆盖它。还应注意,您可以使用docker attach附加到任何正在运行的容器。这么多解决方案有不同的解我只是没有看到需要提交图像。这似乎没必要。

Docker exec的文档 - https://docs.docker.com/engine/reference/commandline/exec/

Docker的文档附加 - https://docs.docker.com/engine/reference/commandline/attach/


-11
投票
docker container start <CONTAINER_ID>

-12
投票

我实际上不同意这两个答案。如果您只想查看容器中的内容,则可以运行此命令来获取shell。无需更改入口点或任何配置。

docker run -it <image_name> bash
© www.soinside.com 2019 - 2024. All rights reserved.