When a Docker container starts, it executes an application or command. The container may get this executable (script or file) from its image’s configuration. In addition, we may set the executable as an option from the command line at execution time. Most of the time, we build our images from a parent image we get from a public repository, meaning its author has probably already defined the executable. The main way to do that is with the ENTRYPOINT and CMD Dockerfile instructions.
In this tutorial, we start with a brief description of the ENTRYPOINT and CMD instructions. Then we examine ways to override them.
2. The CMD and ENTRYPOINT Instructions
We can use the CMD and ENTRYPOINT Dockerfile instructions to define an executable file the container will run. The CMD instruction can be used together with the ENTRYPOINT instruction.
2.1. The ENTRYPOINT Instruction
The ENTRYPOINT instruction’s sole purpose is to point to an executable file that the container will run. It has two forms:
- exec form
- shell form
In the exec form, we enter the executable file and its arguments as an array of strings with quotes:
ENTRYPOINT ["echo", "Hello World of Docker"]
This form is preferred to the shell form. In the latter, we enter the executable and its arguments as we would in a shell:
ENTRYPOINT echo Hello World of Docker
The result of the above instruction will be the same as the exec form. However, there are two important points:
- Docker will execute the command by invoking /bin/sh
- we can’t supply extra arguments through either CMD or docker run
Of course, this brings us to the CMD instruction.
2.2. The CMD Instruction
There are two main uses of CMD. The first one is to set the executable that the container will run:
CMD ["echo","Hello World of Docker with CMD"]
The result is similar to the ENTRYPOINT instruction with the same syntax. This means that if we start our container with the docker run command, it will run the echo command. Similarly, there is also a shell form of the CMD instruction.
Apart from the above case, we may use the CMD instruction together with the ENTRYPOINT instruction. In that case, we set the executable in the ENTRYPOINT instruction and add extra arguments with the CMD instruction:
ENTRYPOINT ["echo","-e"] CMD ["Hello\tWorld"]
As can be seen, we set the container to run the echo -e command with the ENTRYPOINT instruction. Then, we use CMD to define the string we want to output. To sum up, the container will execute the command echo -e Hello\tWorld.
3. The docker run Command
The docker run command has some options for setting or overriding the CMD and ENTRYPOINT instructions of the Dockerfile.
3.1. Building an Example Dockerfile
To better understand how things work, let’s create an example Dockerfile. It will execute the echo command like the examples in the previous section:
FROM ubuntu:latest ENTRYPOINT ["echo","-e"] CMD ["Hello\tWorld"]
In the Dockerfile, we set our parent image to the latest version of Ubuntu. Also, we set the ENTRYPOINT and CMD instructions to run the echo -e command and print the Hello\tWorld string. Next, we build our image and run the container:
$ sudo docker run -it example1 Hello World
To make things clear, we’ve tagged the image as example1 with the docker build command. Moreover, the -it option of the docker run command runs the container in the foreground.
3.2. Override CMD With the docker run Command
We may set the COMMAND option of the docker run command and override the CMD instruction. In the previous example, we can change the docker run command:
$ sudo docker run -it example1 "Hello\tWorld\tof Docker Run" Hello World of Docker Run
Here, we replaced the string with Hello\tWorld\tof Docker Run. We’ve effectively overridden the CMD value Hello\tWorld of the Dockerfile.
Of course, the CMD instruction was used to set extra options to the ENTRYPOINT instruction. Hence, we can change the echoed string without rebuilding our image. Note that we may also set an entry point with the docker run –entrypoint option.
4. Overriding CMD by Inheriting a Parent Image
Let’s create another example Dockerfile:
FROM example1:latest CMD ["Hello World\tOverriding parent image"]
Instead of ubuntu:latest, our parent image is now example1:latest. Note that this is the image that we built in the previous section. Moreover, we can now set another CMD instruction that will override the original CMD instruction value of the parent image. After building our image, we can run the container:
$ sudo docker run -it example2 Hello World Overriding parent image
As a result, our new container echoed the content of the CMD instruction that we set in the Dockerfile of the example2 image. So, the CMD instruction of the parent image was effectively overridden.
5. Overriding CMD With Docker Compose
The docker-compose tool packages an application from the underlying images and their resources. It is possible to override the command of an image with the docker-compose configuration file. Let’s create a file with the name docker-compose.yaml. There we may enter:
version: '2.2' services: echoer: image: example1 command: "Hello World, from docker-compose"
So, we define one service with the name echoer. This service is based on the example1 image in the previous section. We’ll override the CMD instruction of the example1 image with the command element of the docker-compose.yaml configuration file:
$ sudo docker-compose up Creating network "example1_default" with the default driver Creating example1_echoer_1 ... done Attaching to example1_echoer_1 echoer_1 | Hello World, from docker-compose example1_echoer_1 exited with code 0
Here, the docker-compose up command creates and starts the containers. We observe that the container printed the YAML file string instead of the Dockerfile string. So, we’ve effectively overridden the CMD instruction.
6. Overriding CMD With the docker-compose run Command
Similar to the docker run command, we can override the CMD instruction with the docker-compose run command. In the previous example, we can run the service echoer and enter the COMMAND option to the docker-compose run command:
$ sudo docker-compose run echoer "Hello World, CMD Overriden from docker-compose run" Hello World, CMD Overriden from docker-compose run
As can be seen, we’ve effectively overridden the CMD instruction once again.
In this article, we examined ways to override the CMD instruction of the Dockerfile configuration file. We created a very simple Docker image and demonstrated some sample use cases.