A lot of people don’t get the difference to this and I think creack over at stackoverflow did a great job explaining this:

Docker has a default entrypoint which is /bin/sh -c but does not have a default command.

The command is run via the entrypoint. i.e., the actual thing that gets executed is /bin/sh -c bash. This allowed docker to implement RUN quickly by relying on the shell’s parser. Later on, people asked to be able to customize this so ENTRYPOINT and -entrypoint has been introduced.

When using the CMD instruction, it is exactly as if you were doing docker run -i -t ubuntu <cmd>. <cmd> will be the parameter of the entrypoint.

And he notes that when using an image like the ubuntu provided one:

You will also get the same result if you instead type docker run -i -t ubuntu. You will still start a bash shell in the container because of the ubuntu Dockerfile specified a default CMD: CMD ["bash"]

One thing to note is that ENTRYPOINT can be changed to a binary and CMD can be the arguments you want to pass in to that command:

As everything is passed to the entrypoint, you can have a very nice behavior from your images. When using ["/bin/cat"] as entrypoint and then doing docker run catimg /etc/passwd, you get it, /etc/passwd is the command and is passed to the entrypoint so the end result execution is simply /bin/cat /etc/passwd.

Now, lets say there are some other commands you want to execute at container start. The simplist way to do this would be the very common “run” file which is merely a bash script running the commands you want…with the last command being the process you need running:

#!/bin/bash
DEST_HOST="example.com"
DEST_PORT="443"
LOCAL_PORT="443"

ncat -l -p $LOCAL_PORT -k --sh-exec "ncat $DEST_HOST $DEST_PORT"

In your Dockerfile, just add in that file:

# Example dockerfile
FROM debian:stable

a bunch of stuff...

ADD run /opt/run
CMD ["/opt/run"]

Additionally, you can provide additional parameters to both CMD and ENTRYPOINT:

For example, invoking nmap:

ENTRYPOINT ["nmap", "-sS"]
CMD ["192.168.1.2", "192.168.1.5"]

Enjoy Containerizing.. :)

Mario Loria is a builder of diverse infrastructure with modern workloads on both bare-metal and cloud platforms. He's traversed roles in system administration, network engineering, and DevOps. You can learn more about him here.