如何在Dockerfile中正确运行Docker cmds

Docker在Dockerfile中运行命令的方式与在启动容器后手动运行命令之间似乎有区别。 这似乎是由于你可以启动一个shell,一个(我假设)非Dockerfile与交互式shell之间运行诸如docker run -it docker run -it <some-img-id>非交互式shell。

我怎样才能在Docker容器中debugging运行命令,使其运行完全像命令从Dockerfile运行? 只是将/bin/bash --noprofile添加到run cmd就足够了吗? 或者从Dockerfile启动时环境还有什么不同?

你正在经历的是由于shell的行为。 大部分的使用习惯使用bash shell。 所以一般我们会尝试以下面的方式运行这些命令

对于新的容器

 docker run -it <imageid> bash 

对于现有的容器

 docker exec -it <containerid> bash 

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

 RUN echo Testing 

那么它相当于运行/bin/sh -c 'echo Testing' 。 所以你可以期望有一些差异,因为两个炮弹都不一样。

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

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

这将使RUN命令作为bash -c 'echo Testing' 。 您可以在这里了解更多关于SHELL指令

简答1:

如果Dockerfile不使用USERSHELL命令,那么这个:

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

简短的回答2:

如果在构build之后不压缩或压缩图像,则Docker会为每个Dockerfile命令创build图像层。 你可以在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 

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

 docker run -it 5a5964bed25d cmd 

长答案1:

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

  • cmd作为参数执行图像的默认入口点。 入口点存储在ENTRYPOINT命令的图像上。 也就是说,如果cmdmy-app并且入口点是/bin/sh -c ,则执行/bin/sh -c my-app
  • 使用Dockerfile中最后一个USER命令定义的图像的默认用户标识来启动它
  • 从映像的Dockerfile commulative中的所有ENV命令的环境variables启动它

当docker docker build运行Dockerfile RUN ,它确实是完全相同的,只有在Dockerfile的当前(线)存在的值。

所以确切的说,你必须在RUN行之前取ENVs和最后一个USER命令的值,并使用docker docker run命令中的值。

最常见的映像有/bin/sh -c/bin/bash -c作为入口点,最有可能的是该构build以root用户身份运行。 因此, docker --entrypoint "/bin/bash -c" -u root <image> cmd应该就足够了