Docker文件中Docker如何运行命令与启动容器后手动运行命令之间似乎存在差异。这似乎是由于你可以启动的shell类型,一个(我假设)非交互式shell,当运行像docker run -it <some-img-id>
之类的东西时,它使用Dockerfile而不是交互式shell。
如何调试Docker容器中的运行命令,使其运行方式与从Dockerfile运行的命令完全相同?只需将/bin/bash --noprofile
添加到run
cmd即可吗?或者从Dockerfile启动时有什么不同的环境吗?
答案 0 :(得分:1)
简答1:
如果Dockerfile没有使用USER
和SHELL
命令,那么:
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
命令构建的映像中。即如果cmd
为my-app
且入口点为/bin/sh -c
,则会执行/bin/sh -c my-app
。USER
命令定义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