如何在Dockerfile中运行Docker cmds

时间:2017-07-29 20:55:18

标签: bash shell docker dockerfile interactive

Docker文件中Docker如何运行命令与启动容器后手动运行命令之间似乎存在差异。这似乎是由于你可以启动的shell类型,一个(我假设)非交互式shell,当运行像docker run -it <some-img-id>之类的东西时,它使用Dockerfile而不是交互式shell。

如何调试Docker容器中的运行命令,使其运行方式与从Dockerfile运行的命令完全相同?只需将/bin/bash --noprofile添加到run cmd即可吗?或者从Dockerfile启动时有什么不同的环境吗?

2 个答案:

答案 0 :(得分:1)

简答1:

如果Dockerfile没有使用USERSHELL命令,那么:

docker --entrypoint "/bin/sh -c" -u root <image> cmd

简答2:

如果您在构建后没有挤压或压缩图像,Docker会为每个Dockerfile命令创建图像层。您可以使用docker build在每个步骤结束时在--->的输出中看到它们:

Step 2/8 : WORKDIR /usr/src/app
  ---> 5a5964bed25d # <== THIS IS IMAGE ID OF STEP 2
Removing intermediate container b2bc9558e499
Step 3/8 : RUN something
  ---> f6e90f0a06e2 # <== THIS IS IMAGE ID OF STEP 3
Removing intermediate container b2bc9558e499

在您要调试的RUN步骤之前查找图像ID(例如,您要调试上面的步骤3,执行步骤2图像ID)。然后只需在该图像中运行命令:

docker run -it 5a5964bed25d cmd

长答案1:

当您运行docker run [image] cmd Docker实际上以这种方式启动cmd时:

  • cmd为参数执行图像的默认入口点。入口点存储在Dockerfile中由ENTRYPOINT命令构建的映像中。即如果cmdmy-app且入口点为/bin/sh -c,则会执行/bin/sh -c my-app
  • 以图像的默认用户ID启动它,该用户ID由Dockerfile中的最后一个USER命令定义
  • 使用来自image&#39} Dockerfile的所有ENV命令的环境变量启动它

docker build运行Dockerfile RUN时,它只会与Dockerfile的当时(行)存在的值完全相同。

确切地说,您必须在RUN行之前获取ENVs的值和最后一个USER命令,并使用docker run命令中的那些。

大多数常见图片都以/bin/sh -c/bin/bash -c作为入口点,而且很可能构建版本与root用户一起运行。因此docker --entrypoint "/bin/bash -c" -u root <image> cmd应该足够了

答案 1 :(得分:1)

您遇到的是因为shell而导致的行为。我们大多数人都习惯使用bash shell。因此,通常我们会尝试以下面的方式运行命令

适用于新容器

docker run -it <imageid> bash

对于现有容器

docker exec -it <containerid> bash

但是当我们在Dockerfile中使用RUN指令指定一些命令时

RUN echo Testing

然后它相当于运行/bin/sh -c 'echo Testing'。所以你可以期待一些差异,因为两个shell都不同。

在Docker 1.12或更高版本中,您有一个名为SHELL的Dockerfile指令,这允许您覆盖默认的SHELL

SHELL ["/bin/bash", "-c"]
RUN echo Testing

这将使RUN命令执行为bash -c 'echo Testing'。您可以详细了解SHELL指令here