ENTRYPOINT and CMD

ENTRYPOINT

The ENTRYPOINT directive in a Dockerfile is used to define the executable that always runs when the container starts. This ensures consistent behavior for the container's main process.

  • Purpose: Sets the command to execute when the container starts.
  • Behavior: The ENTRYPOINT command is mandatory and always executed.
  • Example:
    # Define the entry point for the container
    ENTRYPOINT ["executable"]
    
    # Example: Always run the Python3 interpreter when the container starts
    ENTRYPOINT ["python3"]
    

CMD

The CMD directive specifies the default arguments or commands to pass to the ENTRYPOINT. If ENTRYPOINT is not defined, CMD directly runs as the container's command.

  • Purpose: Defines the default command or arguments for the container's executable.
  • Behavior: Only one CMD instruction is allowed in a Dockerfile. If multiple are present, only the last one takes effect.
  • Example:
    # Specifies the default argument for ENTRYPOINT or the default command to execute
    CMD ["app.py"]
    
    # Run specific commands
    CMD ["executable", "param1", "param2"]
    
    # Example with Python3 and a script
    ENTRYPOINT ["python3"]
    CMD ["app.py"]
    
    # Another example with npm start
    ENTRYPOINT ["npm"]
    CMD ["start"]
    

When to Use Which?

1. When to Use ENTRYPOINT?

Use ENTRYPOINT when you always want the container to run a specific command, making it behave like an executable. This is useful when your container is designed for a dedicated task, such as running a web server, database, or agent.

Use Case:
- Running an Nginx web server.

Dockerfile:

FROM nginx
ENTRYPOINT ["nginx", "-g", "daemon off;"]
Explanation: Every time the container starts, it runs nginx -g "daemon off;", ensuring that the Nginx server starts.

Command to Run the Container:

docker run -d my-nginx
The container will always start Nginx, regardless of any command-line arguments passed.


2. When to Use CMD?

Use CMD when you want to provide a default command that users can override at runtime.

Use Case: - Running a Python script but allowing flexibility to execute different scripts.

Dockerfile:

FROM python:3.9
CMD ["python3", "app.py"]
Explanation: By default, app.py will run when the container starts, but users can override it.

Command to Run the Container:

docker run my-python-app
(Default behavior: runs python3 app.py)

Override CMD at Runtime:

docker run my-python-app python3 another_script.py
CMD is replaced by python3 another_script.py.


3. When to Use Both ENTRYPOINT and CMD Together?

Use both when you want a fixed entry command (ENTRYPOINT) but allow flexible arguments (CMD).

Use Case: - Running a Python interpreter but allowing different scripts as arguments.

Dockerfile:

FROM python:3.9
ENTRYPOINT ["python3"]
CMD ["app.py"]
Explanation: ENTRYPOINT forces the container to always run python3. CMD provides a default script (app.py) that can be overridden.

Command to Run the Container:

docker run my-python-container
(Default behavior: runs python3 app.py)

Override CMD at Runtime:

docker run my-python-container another_script.py
python3 another_script.py runs instead.


4. How Overriding Works?

Case ENTRYPOINT CMD Run Behavior
Only CMD Not Set ["app.py"] Runs app.py
Only ENTRYPOINT ["python3"] Not Set Runs python3 (without arguments)
Both ENTRYPOINT + CMD ["python3"] ["app.py"] Runs python3 app.py
Override CMD ["python3"] ["app.py"] docker run my-python-container script.py → Runs python3 script.py
Override ENTRYPOINT ["python3"] ["app.py"] docker run --entrypoint /bin/bash my-python-container → Runs /bin/bash

Override ENTRYPOINT at Runtime:

docker run --entrypoint /bin/sh my-python-container
Runs a shell instead of python3.

Override Both ENTRYPOINT and CMD:

docker run --entrypoint node my-python-container server.js
Runs node server.js instead of python3 app.py.


Best Practices:

  • Use ENTRYPOINT when the container is an executable (e.g., nginx, python3, java).
  • Use CMD when you need a default command that users can override (e.g., python3 app.py).
  • Use both together when you want a fixed command with flexible arguments.
  • Override CMD by passing arguments to docker run.
  • Override ENTRYPOINT using --entrypoint.

Additional Notes

1. ENTRYPOINT and CMD Together

  • ENTRYPOINT specifies the executable.
  • CMD provides the arguments for the executable.

Example:

ENTRYPOINT ["echo"]
CMD ["Hello, sweetheart"]
When the container starts, it will execute:
echo Hello, sweetheart

2. Multiple CMDs

  • A Dockerfile cannot have multiple CMD instructions executed simultaneously.
  • Only the last CMD instruction will take effect.

Combining Commands in CMD

Option 1: Use Shell Form

You can use the shell form of CMD to chain multiple commands:

CMD ["sh", "-c", "npm start && python3 app.py && echo 'Hello, sweetheart'"]

Option 2: Use an Entrypoint Script

You can create a shell script to handle multiple commands, copy it into the container, and set it as the CMD:

  1. Create the script:

    # entrypoint.sh
    npm start
    python3 app.py
    echo "Hello, sweetheart"
    

  2. Use the script in the Dockerfile:

    COPY entrypoint.sh /usr/local/bin/entrypoint.sh
    RUN chmod +x /usr/local/bin/entrypoint.sh
    CMD ["/usr/local/bin/entrypoint.sh"]
    

  3. Alternatively, use a different script:

    COPY run_commands.sh /usr/local/bin/
    RUN chmod +x /usr/local/bin/run_commands.sh
    CMD ["/usr/local/bin/run_commands.sh"]
    

This guide provides a comprehensive overview of the ENTRYPOINT and CMD directives in Dockerfiles, including their purposes, behaviors, and examples of how to use them effectively. ```