logo
Published on

Entrypoint and Command

Authors
  • avatar
    Name
    Bowen Y
    Twitter

What is the difference between CMD and ENTRYPOINT?

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

When you run docker like this: docker run -i -t ubuntu bash the entrypoint is the default /bin/sh -c, the image is ubuntu and the command is bash.

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 were introduced.

Everything after the image name, ubuntu in the example above, is the command and is passed to the entrypoint. When using the CMD instruction, it is exactly as if you were executing docker run -i -t ubuntu "<cmd>" The parameter of the entrypoint is "<cmd>".

You will also get the same result if you instead type this command docker run -i -t ubuntu: CMD ["bash"].

As everything is passed to the entrypoint, you can have a very nice behavior from your images. @Jiri example is good, it shows how to use an image as a "binary". When using ["/bin/cat"] as entrypoint and then doing docker run img /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.

Another example would be to have any cli as entrypoint. For instance, if you have a redis image, instead of running docker run redisimg redis -H something -u toto get key, you can simply have ENTRYPOINT ["redis", "-H", "something", "-u", "toto"] and then run like this for the same result: docker run redisimg get key.

reference: https://stackoverflow.com/questions/21553353/what-is-the-difference-between-cmd-and-entrypoint-in-a-dockerfile

Will docker exec use Entrypoint as the executable file?

No, when you use docker exec to run a command in a running container, it does not use the ENTRYPOINT as the executable to run your command. Instead, docker exec runs the command you specify directly within the container.

Here's how it works:

docker exec Usage: The docker exec command is typically used to run a new command in a running container. For example, if you run docker exec [container_id] mycommand, it executes mycommand inside the running container.

Independence from ENTRYPOINT and CMD: This command execution is independent of the ENTRYPOINT and CMD instructions defined in the Dockerfile. These instructions (ENTRYPOINT and CMD) determine what the container runs at startup, not what happens when you use docker exec.

Practical Example: Suppose you have a container running a web server, started with its own ENTRYPOINT and/or CMD instructions. If you run docker exec [container_id] ls /var/www/html, this will list the contents of /var/www/html in the container. This ls command is executed independently and does not involve the container's ENTRYPOINT or CMD.

In summary, docker exec is used for executing new commands in a running container, and it does this independently of the container's ENTRYPOINT or CMD configuration.

The ENTRYPOINT and CMD instructions in a Dockerfile define behavior that is specific to the docker run command, which is used to create and start a new container.

Example Entrypoint file

#!/bin/sh
set -e

# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
	set -- php-fpm "$@"
fi

exec "$@"
  • This block checks if the first argument ($1) to the script starts with a dash (-). This is a common convention for passing options or flags to a command.
  • ${1#-} is a shell parameter expansion that removes a leading hyphen (-) from the first argument $1. If $1 doesn't start with a hyphen, ${1#-} equals $1.
  • If $1 starts with a -, indicating that it's an option/flag rather than a command, the script prepends php-fpm to the arguments list. set -- php-fpm "$@" resets the positional parameters ($@) of the script, effectively transforming the script's arguments from, for example, -f myconfig.conf to php-fpm -f myconfig.conf.
  • This is useful for allowing users to pass options to php-fpm when running the Docker container without needing to explicitly specify the php-fpm command.

exec "$@":

  • Finally, exec "$@" replaces the current shell with the command specified in the arguments.
  • $@ is a special variable that holds all of the script's arguments.
  • Using exec here ensures that the final command (e.g., php-fpm with any passed options) becomes the main process of the container (PID 1). This is important in Docker containers because the container lives as long as this main process.

In summary, this script is an entrypoint script for a Docker container running PHP-FPM. It allows the container to be started with or without additional command-line options for php-fpm. If the first argument is an option (starts with -), it prepends php-fpm to the arguments, and then it executes this command. This pattern is particularly useful for creating flexible Docker images that can be easily configured with different settings at runtime.