1. 概述

在这篇教程中,我们将探索不同的方法以使 Docker 容器无限期运行。

默认情况下,容器只在默认命令执行时运行,但在调试和故障排除时通常会无限期运行它们。

2. Docker 运行基础

让我们来看看 docker run 命令的一些基本知识,以及在启动容器时如何传递命令。

2.1. 规定要运行的命令

在创建 Dockerfile 时,有以下两种方式来指定要运行的命令:

  • ENTRYPOINT 指令 规定了容器的命令。这对于除非用户明确覆盖它们外总是希望运行的命令非常有用。
  • 我们还可以使用 CMD 指令来定义默认命令或要传递给容器的参数。用户在图像名称后添加的任何参数将替换整个 CMD 指令。

2.2. 覆盖默认命令

要覆盖 CMD 指令,我们只需在 docker run [image_name] 后添加另一个命令:

docker run ubuntu echo "Hello World"

要覆盖 ENTRYPOINT 指令,我们需要添加 -entrypoint 标志和期望的命令,然后在图像名称之前,并在图像名称之后添加任何参数:

docker run --entrypoint echo ubuntu "Hello World"

两个示例都将在容器启动时运行命令 echo “Hello World”

2.3. 使用命令的 Docker 运行

docker run 命令的默认行为可以概括为以下几点:

  • 除非明确使用 -d 标志脱离后台运行,否则容器在前台运行。
  • 容器运行直到指定的命令停止运行并停止。

让我们看一个这个例子:

docker run ubuntu bash

上面的命令将在 ubuntu 图像中运行 bash 命令。bash 命令在容器中启动一个 shell。

命令运行,但容器在命令完成时停止,这几乎立即发生。我们可以使用 docker ps 命令进行测试:

docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
c8f8f8f8f8f8        ubuntu              bash                2 minutes ago      Exited (0)          22/tcp               mystifying_snyder

3. 无限期运行 Docker 容器

默认情况下,容器可能设计成无限期运行或不运行。例如,包含 Web 服务器的容器仅在 Web 服务器运行时运行。然而,包含一次性任务(如 cron 作业)的容器仅运行很短时间。

让我们看看一些运行容器无限期的方法。

3.1. 永不停止的命令

最简单的方法是传递永远不会结束的命令来保持容器运行。

我们可以使用 tail -f 命令读取 /dev/null 文件。此命令持续查找文件中的新更改以显示,因此只要文件存在就永远不会结束:

docker run ubuntu tail -f /dev/null

我们可以使用以下命令运行无限循环,它什么也不做:

docker run ubuntu while true; do sleep 1; done

我们可以使用以下命令让容器闲置并什么也不做:

docker run ubuntu sleep infinity

我们可以使用永不停止的命令以以下方式之一:

  • Dockerfile 中的 ENTRYPOINTCMD 指令
  • docker run 命令中覆盖 ENTRYPOINTCMD

在前台运行永不停止的命令并陷入僵持终端是没有意义的。在这种情况下,我们可以使用 -d 标志将容器在后台运行

3.2. 启动伪终端

永不停止的命令很久以前是一种没有其他选项时的临时解决方案。然而,在 Docker 的最新版本中,通过与容器一起在前台和后台启动终端会话,有可能保持容器运行。

伪终端用于在容器内运行命令。为了在容器中启动伪终端会话,我们可以使用 -t 标志。 容器不会退出,直到会话结束。

如果我们想要与容器交互,我们可以将此与 -i 标志结合使用。这将允许我们使用终端在容器中运行命令:

docker run -it ubuntu bash

或者,如果我们的目的是仅让容器无限期运行,我们可以使用 -d 标志:

docker run -d -t ubuntu

4. 总结

在这篇文章中,我们学习了一些使 Docker 容器无限期运行的方法。我们讨论了向容器传递命令的方式,并对这些命令进行了修改以解决问题。我们还触及了使用伪终端会话保持容器运行的现代解决方案。