如何在同一终端内停止正在运行的Docker容器?

5
我已经创建了一个以编译我的(Golang)代码并运行已编译的二进制文件结束的Dockerfile
# Compile my Go code
RUN go build -o bin *.go

# Run the binary
CMD /root/src/whisky/bin

在构建了镜像后(docker build -t whisky .),我运行了镜像(docker run --name whisky whisky_image)。程序开始在终端输出。
当我从我的笔记本电脑上运行程序时,我可以随时使用CTRL+C停止它,但现在它正在容器内运行,按CTRL+C没有任何作用。容器只是不断地输出,没有任何停止的迹象。
我仍然可以从另一个终端docker stop whisky停止容器,但我想知道是否有更好的方法。
有人知道在容器中停止命令或在同一终端中停止整个容器的推荐方法吗?
[编辑]
根据提供的答案,我学到我可以使用-d在分离模式下运行容器,然后使用docker logs container_id --follow跟踪容器日志。虽然这样做可行,但我更喜欢直接运行容器(非分离模式),因为那样我就不会犯将其在后台运行并忘记它的错误了。
有人知道如何以一种方式运行容器,可以通过按CTRL+C在同一终端中停止它吗?

为什么不以分离模式运行它,并从docker logs -f CONTAINER查看日志? - LinPy
你如何启动容器?你是否分配ttydocker run -it my_image - Adiii
如果您运行附加到容器的容器,则 Ctrl+C 将停止容器。 - 4xy
“但现在它正在容器内运行,按下CTRL+C没有任何反应”这句话是什么意思?你使用了哪个命令处于这种状态? - Pierre B.
@kramer65,你尝试过使用答案中建议的-it吗?这有帮助吗? - funnydman
7个回答

2
你可以使用“-d”——>在分离模式下。
[编辑] 补充说明。之后,您可以使用以下命令尾随日志
docker logs container_id --follow

虽然这个方法可行,但实际上并没有回答问题。你有任何想法为什么我无法在非分离模式下停止正在运行的容器吗?我稍微编辑了一下问题。 - kramer65

2

分配一个伪终端 (-t),然后您可以通过按下 CTRL+C 来控制输出:

$ docker run --name whisky -t whisky_image
^C

但容器仍将运行,因此还需添加标准输入 (-i):

$ docker run --name whisky -ti whisky_image
^C

但容器仍将存在(参见docker ps -a - 处于退出状态),因此您可以添加清理标志--rm

$ docker run --name whisky --rm -ti whisky_image
^C

请查看Docker运行文档了解更多细节。


1
你需要使用 init 命令来运行你的容器。
docker run --init --name whisky whisky_image

然后使用Ctrl+C 杀掉它。

init将会把你的程序作为PID 1启动。


1

如前所述,有两种可能性,第一种是分离进程(-d选项),或使用带交互模式的TTY(-ti选项)。

分离版本将允许您工作和管理实例,但不会让您通过按下CTRL+C来关闭它。

带有交互模式(-i)的TTY版本可以。

因此,docker run -it应该解决问题。

Docker Run参考Docker容器进程行为也可以提供帮助。


0

试试这个:

# Compile my Go code
RUN go build -o bin *.go

# Run the binary
CMD ["/root/src/whisky/bin"]

这是 exec 形式。在此形式中,您的可执行文件被直接调用。 您使用的是 shell 形式,它使用 /bin/sh -c 启动进程。此形式不会自动将信号传递给子进程。

0

Dockerfile

FROM golang

WORKDIR /go/src/app

ADD . .

# Compile my Go code
RUN go build -o bin *.go

# Run the binary
CMD /go/src/app/bin

Go程序

package main

import (
    "fmt"
    "time"
)

func main() {

    for {
        fmt.Println("\nWHISKY TIME: ", time.Now().String())
        time.Sleep(time.Second)
    }
}

构建容器

╭─exadra37@exadra37-Vostro-470 ~/Developer/DevNull/stackoverflow  
╰─➤  sudo docker build -t whisky . 
Sending build context to Docker daemon  3.072kB
Step 1/5 : FROM golang
 ---> c4d6fdf2260a
Step 2/5 : WORKDIR /go/src/app
 ---> Using cache
 ---> ab35c58a3608
Step 3/5 : ADD . .
 ---> 320a51d3e579
Step 4/5 : RUN go build -o bin *.go
 ---> Running in 5db9f4a9cbe1
Removing intermediate container 5db9f4a9cbe1
 ---> e16b272606da
Step 5/5 : CMD /go/src/app/bin
 ---> Running in f66039aeb53a
Removing intermediate container f66039aeb53a
 ---> d453f9e10c49
Successfully built d453f9e10c49
Successfully tagged whisky:latest

运行容器

╭─exadra37@exadra37-Vostro-470 ~/Developer/DevNull/stackoverflow  
╰─➤  sudo docker run -it --name whisky whisky                                                                                                                                                                137 ↵

WHISKY TIME:  2019-11-25 16:19:26.397705029 +0000 UTC m=+0.000041700

WHISKY TIME:  2019-11-25 16:19:27.399189969 +0000 UTC m=+1.001526690

WHISKY TIME:  2019-11-25 16:19:28.399392173 +0000 UTC m=+2.001728894

WHISKY TIME:  2019-11-25 16:19:29.399566682 +0000 UTC m=+3.001903403
^C%                                                                   

正如您所看到的,我能够使用 CTRL + C 停止它,我只需要使用标志 -it

使用的标志:

╭─exadra37@exadra37-Vostro-470 ~/Developer/DevNull/stackoverflow  
╰─➤  docker run --help | grep "\-t, \-\-tty" -                                                                                                                                                                 2 ↵
  -t, --tty                            Allocate a pseudo-TTY
╭─exadra37@exadra37-Vostro-470 ~/Developer/DevNull/stackoverflow  
╰─➤  docker run --help | grep "\-i, \-\-interactive" -
  -i, --interactive                    Keep STDIN open even if not attached

重启容器

╭─exadra37@exadra37-Vostro-470 ~/Developer/DevNull/stackoverflow  
╰─➤  sudo docker start -i whisky

WHISKY TIME:  2019-11-25 16:21:03.159420042 +0000 UTC m=+0.000047654

WHISKY TIME:  2019-11-25 16:21:04.161264182 +0000 UTC m=+1.001891819

WHISKY TIME:  2019-11-25 16:21:05.161470301 +0000 UTC m=+2.002097939
^C%                                                         

当重新启动容器时,我们只需要使用-i标志,您仍然可以使用CTRL + C停止它。 使用的标志:
╭─exadra37@exadra37-Vostro-470 ~/Developer/DevNull/stackoverflow  
╰─➤  docker start --help | grep "\-i, \-\-interactive" -
  -i, --interactive             Attach container's STDIN

我的回答被踩了并没有什么问题...我甚至提供了一个可行的例子。 - Exadra37

-1

要停止整个容器,请使用以下命令。

 $ docker stop <container>

docker stop 命令停止正在运行的 Docker 容器。它向 Docker 容器内的运行进程发送 SIGTERM 信号并请求其终止。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接