Docker – The ENTRYPOINT instruction

How to install web server (IIS) on Windows Server 2019

The ENTRYPOINT instruction is used to configure a docker image to run like an application or a command. For example, we can use the ENTRYPOINT instruction to make an image that displays help for the curl command. Consider this Dockerfile:

# ENTRYPOINT instruction Dockerfile for Docker Quick Start
FROM alpine
RUN apk add curl
ENTRYPOINT ["curl"]
CMD ["--help"]

We can run the container image with no overriding CMD parameter and it will show help for the curl command. However, when we run the container with a CMD override parameter, in this case, a URL, the response will be to curl the URL. Take a look:

When run parameters are provided to a container that has the exec form of the ENTRYPOINT command, those parameters will be appended to the ENTRYPOINT instruction, overriding anything provided in a CMD instruction. In this example, --help is overridden with the google.com run parameter, so the resulting instruction is curl google.com. Here is the actual syntax for the ENTRYPOINT instruction:

# ENTRYPOINT instruction syntax
ENTRYPOINT command param1 param2 (shell form)
ENTRYPOINT ["executable", "param1", "param2"] (exec form, best practice)

Like the CMD instruction, only the last ENTRYPOINT instruction is significant. Again, this allows you to either use or override the ENTRYPOINT instruction in the FROM image used. Like both the RUN and CMD instructions, using the shell form will invoke a shell as ["/bin/sh", "-c"] (or ["cmd", "/S", "/C"] on Windows). This is not the case when using the exec form of the instruction. This is key if you have an image that does not have a shell or if the shell is not available to the active user context. However, you will not get shell processing, so any shell environment variables will not get substituted when using the exec form of the instruction. It is generally considered best practice to use the exec form of the ENTRYPOINT instruction whenever possible.

The difference between CMD and ENTRYPOINT

Here again, we have two instructions that on the surface seem to be very much the same. It is true that there is some overlap of functionality between the two. Both instructions provide a way to define a default application that is executed when containers are run. However, they each serve their own unique purpose, and in some cases work together to provide greater functionality than either instruction alone. 

The best practice is to use the ENTRYPOINT instruction when you want a container to execute as an application, providing a specific (developer) defined function, and to use CMD when you want to give the user more flexibility in what function the container will serve.

Both of these instructions have two forms: a shell form and an exec form. It is best practice to use the exec form of either whenever possible. The reason for this is that the shell form, by definition, will run ["/bin/sh", "-c"] (or ["cmd", "/S", "/C"] on Windows) to launch the application in the parameter of the instruction. Because of this, the primary process running in the container is not the application. Instead, it is the shell. This affects how the container exits, it affects how signals are processed, and it can really cause problems for images that do not include "/bin/sh". One use case where you might need to use the shell form is if you require shell-environment-variable substitution.

There is also a use case for using both instructions in your Dockerfile. When you use both, you can define a specific application that gets executed when the container is run, and allow the user to easily provide the parameters that get used with the defined application. In this scenario, you would use the ENTRYPOINT instruction to set the application being executed and provide a default set of parameters for the application using the CMD instruction. With this configuration, the user of the container can benefit from the default parameters supplied in the CMD instruction, or they can easily override those parameters used in the application by supplying them as arguments in the container run command. It is highly recommended that you use the exec form of both instructions when you use them together.

Comments are closed.