幸运的是,我使用了-it选项创建容器!
docker ps -a
此命令将修改后的容器状态保存为名为 user/test_image
的新镜像:
docker commit $CONTAINER_ID user/test_image
docker run -ti --entrypoint=sh user/test_image
入口点参数说明:
https://docs.docker.com/engine/reference/run/#/entrypoint-default-command-to-execute-at-runtime
上面的步骤只是使用相同的文件系统状态启动了一个停止的容器,这对于快速调查非常有用;但是环境变量、网络配置、附加卷和其他内容不会被继承。您应该明确指定所有这些参数。
从这里借鉴了启动停止容器的步骤:(最后一条评论)https://github.com/docker/docker/issues/18078
编辑此文件(对应您已停止的容器):
vi /var/lib/docker/containers/923...4f6/config.json
将“路径”参数更改为指向您的新命令,例如/bin/bash。您还可以设置“参数”参数以将参数传递给命令。
重新启动Docker服务(请注意,这将停止所有正在运行的容器,除非您首先启用live-restore):
service docker restart
列出您的容器并确保命令已更改:docker ps -a
启动容器并进入它,现在您应该在您的 shell 中!
docker start -ai mad_brattain
在 Fedora 22 上使用 Docker 1.7.1 工作。
注意:如果您的 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)。
..."Path":"tail","Args":["-f","/dev/null"]...
并且成功了。 - nevromeconfig.v2.json
,您将需要更改Entrypoint
或Cmd
中的任一项。 - flaviut虽然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。我正在使用我的入口脚本运行容器,如下所示: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
脚本以重新运行它,如果您需要以这种方式进行调试。
/bin/sh
而不是cat
-- 这样您只需重启就可以进入。您的解决方案非常棒! - Danny Dulaicat
and /bin/sh
didn't halt execution for me, I ended up looping / sleeping indefinitely. while : do sleep 3600 done
- Jeff Ward使用docker-compose run命令并指定cont_id_or_name参数,进入容器的/bin/bash终端。(为了方便,可以将环境变量和卷挂载在docker-compose.yml文件中)
或者使用docker run命令并手动指定所有参数。
这可能不完全符合你的要求,但是如果你只想检查文件,你可以在已停止的容器上使用 docker export
命令。
mkdir $TARGET_DIR
docker export $CONTAINER_ID | tar -x -C $TARGET_DIR
~/.bashrc
别名文件中,您就会有一个新的巧妙的别名docker-run-prev-container
,它会将您放入上一个容器的 shell 中。docker build
非常有帮助。似乎Docker无法在容器启动后更改入口点,但您可以设置自定义入口点,并在下次重新启动容器时更改入口点的代码。
例如,您可以像这样运行一个容器:
docker run --name c --entrypoint "/boot" -v "./boot":/boot $image
#!/bin/bash
command_a
当您需要使用不同的命令重新启动 C 时,只需更改启动脚本:
#!/bin/bash
command_b
并且重新启动:
docker restart c
docker start -a [container_name]
docker start [container_name]
那么
docker exec -it [container_name] bash
docker exec
无法保持容器的运行。 - dboshardy我的问题:
docker run <IMAGE_NAME>
命令启动了一个容器docker ps -a
时,我可以看到两个容器。docker run <IMAGE_NAME>
命令时,都会创建一个新的镜像解决方案:
docker ps
来获取您的容器的IDdocker container start <CONTAINER_ID>
来启动现有的容器docker exec -it <CONTAINER_ID> /bin/bash
看起来大多数人在修改配置文件时遇到了这个问题,这也是我所做的。我试图为一个具有Vue SPA入口点的PHP / Apache服务器绕过CORS。无论如何,如果您知道你修改的文件,一个简单的解决方案对我有效:
从镜像中复制您修改过的文件:
docker cp bt-php:/etc/apache2/apache2.conf .
在本地修复它
将其复制回去
docker cp apache2.conf bt-php:/etc/apache2/apache2.conf
重新启动容器
*额外加分 - 由于该文件正在被修改,请将其添加到Compose或Build脚本中,以便在正确时它将被烤入镜像!