如何在现有的Docker容器上运行命令?
我用-d
创build了一个容器,所以它不是交互式的。
docker run -d shykes/pybuilder bin/bash
我看到容器已经退出:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d6c45e8cc5f0 shykes/pybuilder:latest "bin/bash" 41 minutes ago Exited (0) 2 seconds ago clever_bardeen
现在我想在机器上运行偶然的命令并退出。 只是为了得到回应。
我试图启动机器。 我试图附加。 我以为我可以打电话与容器run
,但似乎并不被允许。 使用start
似乎运行,然后迅速存在。
退出后我想回到交互模式。
我试过了:
docker attach d6c45e8cc5f0
但是我得到:
2014/10/01 22:33:34 You cannot attach to a stopped container, start it first
但是,如果我启动它,它仍然退出。 赶上22.我不能赢。
在2014年10月, Docker团队介绍了docker exec
命令 : https : //docs.docker.com/engine/reference/commandline/exec/
所以,现在只要知道它的ID(或名称)就可以在正在运行的容器中运行任何命令:
docker exec -it <container_id_or_name> echo "Hello from container!"
请注意, exec
命令仅适用于已经运行的容器。 如果容器当前已停止,则需要先使用以下命令运行它:
docker run -it -d shykes/pybuilder /bin/bash
这里最重要的是-d
选项,代表detached
。 这意味着您最初提供给容器( /bin/bash
)的命令将在后台运行,并且容器不会立即停止 。
你的容器将会退出,因为你的命令将会结束。 使用以下选项来保持它的生命:
- 即使未连接,也要保持STDIN打开。
-
-t
分配一个伪TTY。
所以你的新run
命令是:
docker run -it -d shykes/pybuilder bin/bash
如果您想要附加到已经运行的容器,请执行以下操作:
docker exec -it CONTAINER_ID /bin/bash
在这些例子中, /bin/bash
被用作命令。
为了扩展katrmr的答案,如果容器被停止,并且由于错误而无法启动,则需要将其commit
给图像。 然后你可以在新的图像中启动bash:
docker commit [CONTAINER_ID] temporary_image docker run --entrypoint=bash -it temporary_image
这里的一些答案是误导性的,因为它们涉及正在运行的容器,而不是停止。
Sven Dowideit在Docker论坛上解释说,容器绑定到他们的进程(而且Docker不能改变停止容器的进程,至less由于其内部结构: https : //github.com/docker/docker/issues / 1437 )。 所以,基本上唯一的select是将容器commit
到一个图像,并用不同的命令run
。
见https://forums.docker.com/t/run-command-in-stopped-container/343
(我相信“带参数的ENTRYPOINT
”方法也是行不通的,因为你仍然无法将参数改变为停止的容器。)
所以我觉得答案比上面的许多误导性答案简单。
启动已停止的现有容器
docker start <container-name/ID>
停止正在运行的容器
docker stop <container-name/ID>
然后login到容器的交互式shell
docker exec -it <container-name/ID> bash
创build一个容器并向其发送一个命令:
docker create --name=my_new_container -it ubuntu docker start my_new_container // ps -a says 'Up X seconds' docker exec my_new_container /path/to/my/command // ps -a still says 'Up X+Y seconds' docker exec my_new_container /path/to/another/command
这是我使用上面的CDR LDN答案和我在这里find的答案组成的综合答案。
以下示例从映像启动Arch Linux容器,然后使用pacman
工具在该容器上安装git
:
sudo docker run -it -d archlinux /bin/bash sudo docker ps -l sudo docker exec -it [container_ID] script /dev/null -c "pacman -S git --noconfirm"
就这些。
我必须使用bash -c来运行我的命令: docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"
假设映像使用缺省入口点/bin/sh -c
,运行/bin/bash
将在守护进程模式( -d
)下立即退出。 如果您希望此容器运行交互式shell,请使用-it
而不是-d
。 如果要在通常执行另一个进程的容器中执行任意命令,则可能需要尝试nsenter
或nsinit
。 有关详细信息, 请参阅https://blog.codecentric.de/en/2014/07/enter-docker-container/ 。
不幸的是,使用ENTRYPOINT
docker run --entrypoint
参数来覆盖ENTRYPOINT
是不可能实现这个目标的。
注意:你可以使用–entrypoint覆盖ENTRYPOINT设置,但是这只能将二进制设置为exec(不会使用sh -c)。
简单的答案:同时启动并附加。 在这种情况下,你正在做你所要求的。
docker start <CONTAINER_ID/CONTAINER_NAME> && docker attach <CONTAINER_ID/CONTAINER_NAME>
请务必更改<CONTAINER_ID/CONTAINER_NAME>