buildkit icon indicating copy to clipboard operation
buildkit copied to clipboard

document how to unset ENTRYPOINT

Open mdavis-xyz opened this issue 2 years ago • 9 comments

Solves: https://github.com/docker/docs/issues/16142

mdavis-xyz avatar Feb 12 '23 22:02 mdavis-xyz

I'm not sure I understand what the use-case is here, that justifies why we need to explicitly call this functionality out. Can you explain a bit as to why the user wants to do be able to do this?

jedevc avatar Feb 16 '23 14:02 jedevc

My use case is that I'm using public.ecr.aws/lambda/python. That image has an ENTRYPOINT set which runs a web server. It's for deploying AWS Lambda functions as docker images.

I want to do some debugging after building an image ontop of this. Running docker run --rm -it myimage bash or docker run --rm -it myimage ls or whatever does not work, because of the entrypoint. So I have to unset it.

I'm actually only using this to build, not deploy, so I just want to remove this entrypoint on all the images I build like this, to go back to normal bash.

mdavis-xyz avatar Feb 16 '23 22:02 mdavis-xyz

Running docker run --rm -it myimage bash or docker run --rm -it myimage ls or whatever does not work, because of the entrypoint.

You can just set docker run --rm -it --entrypoint 'bash' public.ecr.aws/lambda/python.

crazy-max avatar Feb 16 '23 22:02 crazy-max

Yes that works.

Although what's the behavior of the --entrypoint command supposed to be? Should it be identical to the ENTRYPOINT line in a dockerfile? For the empty string it is not.

Perhaps the solution is to not clutter the documentation, but instead to just patch buildkit to treat an empty entrypoint line the same as building without buildkit?

mdavis-xyz avatar Feb 17 '23 03:02 mdavis-xyz

Although what's the behavior of the --entrypoint command supposed to be?

--entrypoint string              Overwrite the default ENTRYPOINT of the image

https://docs.docker.com/engine/reference/commandline/run/#options

You can override the ENTRYPOINT setting using --entrypoint, but this can only set the binary to exec (no sh -c will be used).


Should it be identical to the ENTRYPOINT line in a dockerfile? For the empty string it is not.

Plain command if I'm not mistaken (cc @thaJeztah) so if you have in your Dockerfile:

ENTRYPOINT ["executable", "param1", "param2"]

Representation for the flag would be --entrypoint="executable param1 param2".


but instead to just patch buildkit to treat an empty entrypoint line the same as building without buildkit?

WDYM by "empty entrypoint line"? If you mean overwriting entrypoint of the base image inside a Dockerfile this is already covers by the documentation and like @jedevc said no need to have an explicit example for this.

crazy-max avatar Feb 17 '23 10:02 crazy-max

Yeah entrypoint + cmd can be confusing. Entrypoint can be useful if you want the image to be used as an "executable", e.g.

ENTRYPOINT ["/usr/bin/docker"]
CMD ["--help"]

If both an ENTRYPOINT and a CMD are set, then the CMD acts as "default arguments for <entrypoint>", so in the above case, docker run myimage without arguments would run /usr/bin/docker --help. The CMD can be set to provide a is what will be overwritten if the user types a command after the image name, e.g. docker run myimage --version, which would run /usr/bin/docker --version.

Because (as described above), the ENTRYPOINT and CMD are tightly coupled (they're 2 parts of the same thing), it was decided at the time that it made sense that resetting or updating the ENTRYPOINT should also resets the CMD, otherwise you may end up with a situation where the ENTRYPOINT is changed to a completely different command, but the default arguments (CMD) for the old command (entrypoint) would still be used.

The --entrypoint on the commandline only accepts the "shell form" (string), not the JSON (array / exec-form) format. Possibly it could be added, but at the time we decided that this could make things probably more confusing (and ambiguous). The "maybe JSON" approach in the Dockerfile showed many times that it's very easy to make mistakes (['/bin/sh'] is not a valid JSON array but ["/bin/sh"] is; [ is a valid shell command ([ "a" == "b" ]") etc.; so we "try to detect" if it's probably a JSON array, but otherwise fall back to treating it as a string.

In case useful;

  • this was the PR that made updating the ENTRYPOINT reset the CMD; https://github.com/moby/moby/pull/6909
    • related ticket: https://github.com/moby/moby/issues/5147
  • this was the PR that added the ability to reset the entrypoint if it's present https://github.com/moby/moby/pull/23718
    • related ticket: https://github.com/moby/moby/issues/23498

thaJeztah avatar Feb 17 '23 16:02 thaJeztah

LOL, I should probably coin my ticket about warnings for this as well;

  • https://github.com/moby/buildkit/issues/1952

thaJeztah avatar Feb 17 '23 16:02 thaJeztah

WDYM by "empty entrypoint line"?

Sorry, I thought I put a full MWE in the issue ticket, but that was only a summary.

Let's make a MWE using the documentation for docker run, but converted to a Dockerfile.

You can reset a containers entrypoint by passing an empty string, for example: docker run -it --entrypoint="" mysql bash

Dockerfile:

FROM mysql
ENTRYPOINT
CMD ["bash"]

Without buildkit, the build succeeds, and the run command drops me into a shell, as expected.

$ DOCKER_BUILDKIT=0 docker build . -t testentrypoint && docker run --rm -it testentrypoint && echo run exited with $?                                                                       
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM mysql
 ---> 57da161f45ac
Step 2/3 : ENTRYPOINT
 ---> Running in 1ee7153bc879
Removing intermediate container 1ee7153bc879
 ---> ba61f0aa0af0
Step 3/3 : CMD ["bash"]
 ---> Running in 5f89d9c4967d
Removing intermediate container 5f89d9c4967d
 ---> a1590dcd3b37
Successfully built a1590dcd3b37
Successfully tagged testentrypoint:latest
bash-4.4# echo this is an interactive terminal inside the container
this is an interactive terminal inside the container
bash-4.4# exit
exit
run exited with 0

With buildkit, the build succeeds, and the run succeeds in the sense that it doesn't throw an error. But it does not drop me into a shell. It immediately exits the container.

$ DOCKER_BUILDKIT=1 docker build . -t testentrypoint && docker run --rm -it testentrypoint && echo run exited with $?                                                                       
[+] Building 0.1s (5/5) FINISHED                                                               
 => [internal] load build definition from Dockerfile                                      0.0s
 => => transferring dockerfile: 37B                                                       0.0s
 => [internal] load .dockerignore                                                         0.0s
 => => transferring context: 2B                                                           0.0s
 => [internal] load metadata for docker.io/library/mysql:latest                           0.0s
 => CACHED [1/1] FROM docker.io/library/mysql                                             0.0s
 => exporting to image                                                                    0.0s
 => => exporting layers                                                                   0.0s
 => => writing image sha256:a2fc419304fb11a713fb8877fc2aec90819863ddbcbb9c281f19d37ec016  0.0s
 => => naming to docker.io/library/testentrypoint                                         0.0s
run exited with 0

So we get different behaviors with docker run, based on whether buildkit was used to build the image (which builds without throwing errors either way). Should the behavior of a run depend on whether an image was built with buildkit or not?

If using ENTRYPOINT instead of ENTRYPOINT "" or ENTRYPOINT [""] is invalid, then I expect docker build to fail with and without buildkit.

mdavis-xyz avatar Feb 19 '23 22:02 mdavis-xyz

What's the status of this? @crazy-max @thaJeztah Are you requesting changes or think this just should not be merged?

Passing ENTRYPOINT with no argument results in undefined behavior.

Is this something that should be fixed as a bug? Feels logical that it should error.

tonistiigi avatar Feb 10 '24 00:02 tonistiigi