How do I Run Docker cmds Exactly Like in a Dockerfile

試著忘記壹切 提交于 2021-02-11 12:33:31

问题


There seems to be a difference between how Docker runs commands in a Dockerfile versus running commands manually after starting a container. This seems to be due to the kind of shells you can start, a (I assume) non-interactive shell with a Dockerfile vs an interactive one when running something like docker run -it <some-img-id>.

How can I debug running commands in a Docker container so that it runs exactly like the commands are run from a Dockerfile? Would just adding /bin/bash --noprofile to the run cmd suffice? Or is there anything else different about the environment when started from a Dockerfile?


回答1:


What you are experiencing is the behavior because of the shell. Most of us are used to using the bash shell. So generally we would attempt to run the commands in the below fashion

For new container

docker run -it <imageid> bash

For existing container

docker exec -it <containerid> bash

But when we specify some command using RUN directive inside a Dockerfile

RUN echo Testing

Then it is equivalent to running /bin/sh -c 'echo Testing'. So you can expect certain differences as both the shells are different.

In Docker 1.12 or higher you have a Dockerfile directive named SHELL this allows you to override the default SHELL

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

This would make the RUN command be executed as bash -c 'echo Testing'. You can learn more about the SHELL directive here




回答2:


Short answer 1:

If Dockerfile don't use USER and SHELL commands, then this:

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

Short answer 2:

If you don't squash or compress image after the build, Docker creates images layers for each of the Dockerfile commands. You can see them in the output of docker build at the end of each step with --->:

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

Look for the image id just before the RUN step you want to debug (for example you want to debug step 3 on above, take the step 2 image id). Then just run the command in that image:

docker run -it 5a5964bed25d cmd

Long answer 1:

When you run docker run [image] cmd Docker in fact starts the cmd in this way:

  • Executes the default entrypoint of the image with the cmd as its argument. Entrypoint is stored in the image on build by ENTRYPOINT command in Dockerfile. Ie if cmd is my-app and entrypoint is /bin/sh -c, it executes /bin/sh -c my-app.
  • Starts it with default user id of the image, which is defined by the last USER command in Dockerfile
  • Starts it with the environment variables from all ENV commands from image's Dockerfile commulative

When docker build runs the Dockerfile RUN, it does exatly the same, only with the values present at that time (line) of the Dockerfile.

So to be exact, you have to take the value of ENVs and last USER command before your RUN line, and use those in the docker run command.

Most common images have /bin/sh -c or /bin/bash -c as entrypoint and most likely the build operates with root user. Therefore docker --entrypoint "/bin/bash -c" -u root <image> cmd should be sufficient



来源:https://stackoverflow.com/questions/45393971/how-do-i-run-docker-cmds-exactly-like-in-a-dockerfile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!