你是否曾经需要查看Docker容器内部发生了什么?容器旨在是幂等的:如果有问题,重新部署一个新的容器。然而,生活通常并非如此简单。您可能需要在容器中运行命令以识别问题。这就是docker exec
命令能够帮助您的地方。
本文将教您如何使用docker exec
命令在运行中的Docker容器上运行命令。
先决条件
要按照本文中的示例进行操作,您需要遵循以下要求。
- 任何最新版本的Docker Desktop都可以在Windows、Linux或macOS上使用。本教程使用在Windows 10上运行的v3.1.0版本。
启动NGINX容器
Docker exec
在容器中运行命令。但是,在这之前,您必须首先有一个容器来运行这些命令。让我们从下载Docker镜像并创建演示容器开始。
- 创建一个新目录,本教程使用C:\gitrepos\test,用于保存容器使用的文件。
2. 创建一个名为 dockerfile(无扩展名) 的文件,其中包含以下代码。Dockerfile 定义了创建容器所需的步骤。
3. 接下来,在相同的目录中创建一个名为 index.html 的文件,其中包含以下代码。这是一个 HTML 文件,当容器启动时,将显示一个 Hello World 消息。
4. 现在创建 Nginx Docker 容器。由于 Dockerfile 在当前工作目录中,使用 .
指定让 Docker 引擎知道要在那里查找。另外,请确保使用 t
参数为容器打上 my-ngnix
标签,以便将来更容易地引用。

5. 现在容器已构建完成,使用 Docker run 命令启动容器。

6. 最后,打开您的 Web 浏览器并导航至 http://localhost/
,将看到以下内容。

使用 Docker Exec 运行命令
当在Docker容器中运行命令时,可能需要以交互方式运行命令。以交互方式运行命令意味着输入一个命令,获取反馈,输入另一个命令,依此类推。交互式命令会接管您的会话,并阻止您执行其他任何操作。
但是,如果您已经提前知道要发送到容器的命令,并希望在后台运行命令呢?在这种情况下,您可以运行非交互式命令。非交互式命令允许您向Docker发送命令并立即返回控制台的控制权。
查找容器名称和ID
现在,您已经构建了容器,可以在容器内执行命令。在运行命令之前,请找到NGINX容器的名称或ID。在Docker命令中,名称或ID都可以使用。请记住,记住ID可能比记住名称更具挑战性!
要显示任何正在运行的容器信息,请运行Docker ps
命令以输出以下信息。

将唯一的ID e17e4b6be01a
或随机生成的名称 mystifying_chandrasekhar
复制到剪贴板以备将来使用。
使用Docker Exec运行非交互式命令
作为运行非交互式命令的示例,请复制并运行以下命令以返回/var/log目录中文件的列表,使用ls -l
命令。将容器名称 mystifying_chandrasekhar
后面的所有内容传递给Docker exec
命令。

使用Docker命令避免控制台输出
通过立即将Shell控制返回给用户,大型操作避免将控制台占用。通过使用分离的d
选项放弃控制台输出。下面的命令通过在容器内使用touch
命令创建文件/tmp/execWorks,并且不在控制台上显示任何输出。
使用Docker Exec执行交互命令
到目前为止,您已经学会了如何使用docker exec
在Docker容器中运行非交互式命令。但是,可能会有这样的情况,您需要在容器中进行故障排除,例如当您需要交互式地向容器发出命令时。在这种情况下,您需要以交互方式运行命令。
使用docker exec
以交互方式运行命令需要两个选项,i
和t
。i
选项保持STDIN打开,允许将命令发送到容器,t
选项分配一个伪终端(PTY),即一个通信通道,以输入命令。
复制并粘贴以下命令以打开到运行中的Docker容器的交互命令提示符,使用Bourne(sh) shell,如提示更改为/ #
所示。

一旦进入Shell,现在运行下面的命令以演示从容器内列出文件。最后,运行exit
命令以退出交互式Shell。

要在特定目录中打开交互式提示符,请将路径传递给
w
选项,告诉Docker在指定目录中启动shell。
将环境变量传递给运行中的容器
许多程序在启动时使用环境变量来设置配置。例如,大多数Java应用程序需要将JAVA_HOME
环境变量设置为Java路径。
您可以使用e
选项将环境变量传递给会话。例如,也许您需要将名为MYVAR
的环境变量传递给运行中的容器。要执行此操作,请使用e
选项,并像下面所示提供MYVAR="<some value>"
的键/值对。

使用文件传递环境变量
如果有许多环境变量或共享配置,则将这些变量存储在文件中可能更容易。使用--env-file
选项将文件通过相对或绝对路径传递给Docker。此技术通常用于向容器提供安全凭据。务必不要将凭据提交到版本控制!
创建名为env-vars.txt
的文本文件,其中包含要传递的环境变量及其值。此文件可以命名为任何您喜欢的名称,不需要.txt
文件扩展名。

使用env-file
选项将环境变量传递给Docker。使用下面的屏幕截图中所示的echo
命令验证变量是否可用。

以不同用户身份与运行中的容器交互
在生产环境中,应用程序通常以特定用户身份运行以限制其访问权限。如果在生产中以特定用户身份运行应用程序,则在测试命令时也应该这样做。
在此示例中,Docker 容器以 nginx
用户身份运行。通过将用户传递给 w
选项,告诉 Docker 以 nginx
帐户启动容器。在容器内运行的 whoami
命令确认确实使用了 nginx
用户。

nginx
user.下一步
您已经学会使用 docker exec
命令在运行中的容器中执行命令。利用 exec
命令进入并询问运行中的容器,您在故障排除 Docker 容器时拥有了一个强大的新工具。
现在尝试进一步学习,使用 Git 版本控制从容器中拉取静态网站,而不是复制单个文件。如果 Git 对您来说是新的,那么文章《Visual Studio Code 和 Git 的初学者指南》是一个很好的起点。