如何在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不使用USER
和SHELL
命令,那么这个:
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
命令的图像上。 也就是说,如果cmd
是my-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
应该就足够了
- 当从Dockerfile调用脚本时,如何防止出现`#!/ bin / bash:not found`错误
- 如何避免Dockerfile中的大型二进制文件caching失效(Python_Onbuild)