Dockerfile Deep Dive, Part 1: CMD vs ENTRYPOINT and COPY vs ADD

Hello, DevOps Enthusiasts! Mastering Dockerfile instructions is essential for creating efficient, secure, and maintainable container images. In this post, we’ll break down two commonly misunderstood pairs of instructions—CMD vs ENTRYPOINT and COPY vs ADD—through a clear, side-by-side comparison. If you find it helpful, your support will help continue the series! ↻ CMD vs ENTRYPOINT in Dockerfile Both CMD and ENTRYPOINT define the command that runs when a container starts, but they behave differently. CMD CMD defines the default command or arguments that are executed when a container starts—only if no other command is provided at runtime. You can override CMD during container execution by passing a new command to docker run. FROM alpine CMD ["echo", "Hello Readers"] If you execute the container with docker run image-name, it will print: Hello Readers However, if you provide a different command when running the container, it overrides the CMD instruction entirely. For example: docker run image-name echo "Hello Devops Diaries Reader!" This will produce the output: Hello Devops Diaries Reader! This behavior makes CMD useful when you want to define a default command, but still allow users or scripts to run something else if needed. Tip: Use CMD when you want to specify default arguments or commands that can be easily changed by the user at runtime. For example, you might use CMD to set a default shell or script to execute. ENTRYPOINT The ENTRYPOINT instruction defines a command that always executes when the container starts. Unlike CMD, it cannot be overridden by a command passed at runtime unless you explicitly use the --entrypoint flag. If a command is provided during container execution, it is appended to the ENTRYPOINT. FROM alpine ENTRYPOINT ["echo", "Hello Readers"] Output: Hello Readers If we try to override the command by using the same as CMD in the runtime command docker run image-name hello Output: Hello Readers hello In this case, the command gets appended to the ENTRYPOINT. Example with --entrypoint to override the ENTRYPOINT You can override the ENTRYPOINT at runtime using the --entrypoint flag. This allows you to change the command that is executed when the container starts. docker run --entrypoint echo myimage "Hello, Custom Command" In this case, instead of executing the default ENTRYPOINT (which is echo Hello Readers), it will execute echo Hello, Custom Command. ➕ COPY vs ADD in Dockerfile Both COPY and ADD move files into a Docker image — but behave differently. COPY – Clean and Predictable Use it for: Copying local files and folders from your build context. Syntax: COPY Why use it: Only handles local content No extraction or downloading Clear and secure Example: FROM python:3.9 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY app.py . ADD – More Features, More Risk Use it for: Archives and remote URLs. Syntax: ADD Extra features: Extracts .tar, .gz, etc., automatically to the target folder. Downloads from URLs directly into the image. When you use ADD with archives like .tar or .gz, it will automatically extract the contents to the specified target folder. This behavior can save you a step, but it also introduces complexity if you're not expecting it. Examples: Extract an archive: ADD app.tar.gz . In this example, the contents of app.tar.gz will be automatically extracted into the current working directory (.). If you specify a folder, the contents will be extracted to that directory. Download from a URL: ADD https://example.com/file.txt /data/ This command downloads the file.txt from the URL and places it into the /data/ directory inside the Docker image. Best Practice Use COPY by default Use ADD only for extraction or remote URLs (prefer curl or wget instead) Originally posted in here If you found this article helpful, please share it with your DevOps colleagues. Feel free to reach out to me at mail@iamkishorekumar.in with any thoughts or questions. Let’s grow together!

Apr 6, 2025 - 08:03
 0
Dockerfile Deep Dive, Part 1: CMD vs ENTRYPOINT and COPY vs ADD

Hello, DevOps Enthusiasts!

Mastering Dockerfile instructions is essential for creating efficient, secure, and maintainable container images. In this post, we’ll break down two commonly misunderstood pairs of instructions—CMD vs ENTRYPOINT and COPY vs ADD—through a clear, side-by-side comparison.

If you find it helpful, your support will help continue the series!

↻ CMD vs ENTRYPOINT in Dockerfile

Both CMD and ENTRYPOINT define the command that runs when a container starts, but they behave differently.

CMD

CMD defines the default command or arguments that are executed when a container starts—only if no other command is provided at runtime.

You can override CMD during container execution by passing a new command to docker run.

FROM alpine

CMD ["echo", "Hello Readers"]

If you execute the container with docker run image-name, it will print:

Hello Readers

However, if you provide a different command when running the container, it overrides the CMD instruction entirely.

For example:

docker run image-name echo "Hello Devops Diaries Reader!"

This will produce the output:

Hello Devops Diaries Reader!

This behavior makes CMD useful when you want to define a default command, but still allow users or scripts to run something else if needed.

Tip: Use CMD when you want to specify default arguments or commands that can be easily changed by the user at runtime. For example, you might use CMD to set a default shell or script to execute.

ENTRYPOINT

The ENTRYPOINT instruction defines a command that always executes when the container starts.

Unlike CMD, it cannot be overridden by a command passed at runtime unless you explicitly use the --entrypoint flag. If a command is provided during container execution, it is appended to the ENTRYPOINT.

FROM alpine

ENTRYPOINT ["echo", "Hello Readers"]

Output:

Hello Readers

If we try to override the command by using the same as CMD in the runtime command

docker run image-name hello

Output:

Hello Readers hello

In this case, the command gets appended to the ENTRYPOINT.

Example with --entrypoint to override the ENTRYPOINT

You can override the ENTRYPOINT at runtime using the --entrypoint flag. This allows you to change the command that is executed when the container starts.

docker run --entrypoint echo myimage "Hello, Custom Command"

In this case, instead of executing the default ENTRYPOINT (which is echo Hello Readers), it will execute echo Hello, Custom Command.

➕ COPY vs ADD in Dockerfile

Both COPY and ADD move files into a Docker image — but behave differently.

COPY – Clean and Predictable

Use it for: Copying local files and folders from your build context.

Syntax:

COPY  

Why use it:

  • Only handles local content
  • No extraction or downloading
  • Clear and secure

Example:

FROM python:3.9
WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY app.py .

ADD – More Features, More Risk

Use it for: Archives and remote URLs.

Syntax:

ADD  

Extra features:

  • Extracts .tar, .gz, etc., automatically to the target folder.
  • Downloads from URLs directly into the image.

When you use ADD with archives like .tar or .gz, it will automatically extract the contents to the specified target folder. This behavior can save you a step, but it also introduces complexity if you're not expecting it.

Examples:

Extract an archive:

ADD app.tar.gz .

In this example, the contents of app.tar.gz will be automatically extracted into the current working directory (.). If you specify a folder, the contents will be extracted to that directory.

Download from a URL:

ADD https://example.com/file.txt /data/

This command downloads the file.txt from the URL and places it into the /data/ directory inside the Docker image.

Best Practice

  • Use COPY by default
  • Use ADD only for extraction or remote URLs (prefer curl or wget instead)

Originally posted in here

If you found this article helpful, please share it with your DevOps colleagues. Feel free to reach out to me at mail@iamkishorekumar.in with any thoughts or questions. Let’s grow together!