如何在现有的Docker容器上运行命令?

问题描述:

我创建了一个包含-d的容器,因此它不是交互式的。如何在现有的Docker容器上运行命令?

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.我赢不了。

+0

你怎么知道码头集装箱已经退出?你运行了什么命令? – Thufir 2017-11-22 08:54:33

在2014年10月的Docker team introduced docker exec commandhttps://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)的命令将在后台运行,并且容器将不会立即停止

+84

这不适用于停止的容器,仅适用于正在运行的容器。所以如果你有一个立即停止的容器,就像问题一样,这实际上并不能让其他东西在里面运行。 – interfect 2015-02-19 00:55:51

+3

@病毒是正确的,CDR LDN有一个更全面的答案。 – 2015-06-10 19:52:31

+1

所以,高层次的问题是我正在寻求“如何在已经存在的码头集装箱上运行命令?”的答案。而这个解决方案是我正在寻找的确切解决方案。我不需要添加'-it'在docker容器中运行命令。我理解上下文混淆,但这是我确切需要的解决方案。不知道这对于“正确”答案意味着什么,也许标题应该改变?无论哪种方式,这都让我赞不绝口。 – 2016-01-26 22:15:49

假设图像使用默认入口点/bin/sh -c,运行/bin/bash将在守护进程模式(-d)中立即退出。如果您希望此容器运行交互式shell,请使用-it而不是-d。如果要在通常执行另一个进程的容器中执行任意命令,则可能需要尝试nsenternsinit。有关详细信息,请参见https://blog.codecentric.de/en/2014/07/enter-docker-container/

您的容器将出口作为您给它的命令将结束。使用以下选项使其保持活动状态:

  • -i即使未连接,仍保持打开STDIN。
  • -t分配伪TTY。

因此新run的命令是:

docker run -it -d shykes/pybuilder bin/bash 

如果你想连接到一个已经运行的容器:

docker exec -it CONTAINER_ID /bin/bash 

在这些例子中/bin/bash用作命令。

+2

根@本地:〜#搬运工运行 - 它-d shykes/pybuilder斌/庆典 无法找到像“shykes/pybuilder:最新的”本地 拉库docker.io/shykes/pybuilder 泊坞窗:最新标签未找到在仓库docker.io/shykes/pybuilder中。 请参阅“码头运行 - 帮助”。 – 2016-11-16 09:46:48

这里的一些答案是误导性的,因为它们涉及正在运行的容器,而不是停止。 Sven Dowideit在Docker论坛上解释说,容器绑定到他们的进程(并且Docker不能改变停止容器的进程,至少由于其内部结构:https://github.com/docker/docker/issues/1437)。所以,基本上唯一的选择是将commit容器映射到一个图像上,然后用run这个命令来执行一个不同的命令。

https://forums.docker.com/t/run-command-in-stopped-container/343
(我相信“ENTRYPOINT与参数”的做法也不行,因为你仍然无法参数更改为停止容器。)

+0

注意:在没有'-it'的情况下运行'bin/bash'不会改变容器中的任何内容,因此提交它并不是真的必要,CDR LDN为OP的特定情况提供了正确的答案。尽管如此,“提交”是解决如何更改容器过程的技术问题的答案。 – katrmr 2015-03-30 23:33:10

+0

在run-command-in-stopped-container中的candlerb发表评论,建议使用一次性映像和来自非活动容器的卷为我工作:docker run --rm --volumes-from CONTAINER -i busybox tar cO/var/DIR | gzip -c>〜/ mydir_backup.tgz – 2016-05-28 02:11:24

要在katrmr的扩大回答,如果容器被停止,并且由于错误而无法启动,则需要将其commit它映射到图像上。然后你就可以在新的图像推出的bash:

docker commit [CONTAINER_ID] temporary_image 
docker run --entrypoint=bash -it temporary_image 

这是一个组合的回答我提出了使用CDR LDN回答上面,我发现here答案。

下面的示例从图像开头的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"

+1

-c为我工作。奇怪为什么bash独自行不通(没有得到提示) – 2017-03-06 19:00:59

+0

和[this](http://serverfault.com/a/797318)解释了为什么... – 2017-03-06 22:35:34

+0

保存我的一天,谢谢 – Spock 2017-03-15 10:46:06

创建一个容器,将命令发送到它,一个接一个:

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 

不幸的是这是不可能覆盖ENTRYPOINT与与docker run --entrypoint争执以实现此目标。

注意:您可以使用--entrypoint覆盖入口点设置,但 这只能设置二进制给exec(sh的不-c将被使用)。

简单的答案:同时启动并附加。在这种情况下,您正在按照您的要求进行操作。

docker start <CONTAINER_ID/CONTAINER_NAME> && docker attach <CONTAINER_ID/CONTAINER_NAME> 

,一定要更改<CONTAINER_ID/CONTAINER_NAME>

所以我想答案是比上面很多误导性的答案很简单。

要启动它停止

docker start <container-name/ID> 

要停止运行的容器

docker stop <container-name/ID> 

然后登录到一个容器的交互shell现有容器

docker exec -it <container-name/ID> bash 
+0

docker attach 正在运行 – 2017-04-07 01:44:34

+2

@Peter T.实际上,我发现你的答案比别人提供的更简洁。我不明白为什么人们喜欢把一个非常简单的问题复杂化。感谢彼得这个答案。 – 2017-07-14 16:08:02

+0

这需要当你做码头创建,你做到了 - 它https://stackoverflow.com/questions/45216612/docker-getting-exited-just-after-start否则它不会启动..所以你' d执行docker start ,然后执行docker ps -l,开始后你会发现它没有启动。然后附件会失败。所以你必须创造 - 这也是。 – barlop 2018-02-28 05:42:35