Demystifying Docker Instructions: ADD, COPY, CMD, ENTRYPOINT, and RUN

Dockerfiles are the backbone of containerized application development, but some instructions like ADD, COPY, CMD, ENTRYPOINT, and RUN often confuse developers. What do they do? How do they differ? And, most importantly, when should you use them?
Let’s dive deep into these instructions with explanations, examples, and a summary table.
1. ADD vs COPY
Both ADD and COPY are used to transfer files from your local machine (or a remote source) into the Docker image. However, they are not identical. Here's the breakdown:
ADD: More than just copying
The ADD instruction can:
Copy files or directories.
Automatically unpack tar archives into the image.
Download files from a remote URL.
Example:
# Dockerfile
ADD file.tar.gz /app
- If
file.tar.gzis a tar archive, ADD will automatically extract it into/app.
COPY: The simpler alternative
The COPY instruction:
Strictly copies files or directories.
Does not extract tar archives or support remote URLs.
Example:
# Dockerfile
COPY file.tar.gz /app
- The tarball
file.tar.gzis copied as-is to/appwithout being extracted.
When to use ADD vs COPY?
Use ADD when you need to:
Extract tar files automatically.
Fetch files from a URL.
Use COPY for everything else. It’s simpler and more predictable.
2. CMD vs ENTRYPOINT
Both CMD and ENTRYPOINT define what happens when you run a container. But the difference lies in their behavior.
CMD: The default command
The CMD instruction:
Sets the default command or arguments for the container.
Can be overridden when running
docker run.
Example:
# Dockerfile
CMD ["echo", "Hello World"]
Running
docker run <image>→ Outputs:Hello World.Running
docker run <image> echo Goodbye→ Outputs:Goodbye.
ENTRYPOINT: The fixed executable
The ENTRYPOINT instruction:
Specifies the main executable for the container.
Appending arguments to
docker runadds them as parameters to the entrypoint.
Example:
# Dockerfile
ENTRYPOINT ["echo"]
Running
docker run <image>→ Outputs: (nothing, because no arguments were provided).Running
docker run <image> Hello World→ Outputs:Hello World.
When to use CMD vs ENTRYPOINT?
Use CMD for default commands that might change at runtime (e.g., for debugging or testing).
Use ENTRYPOINT for commands that should always run as the main process of the container.
3. RUN vs CMD
Both RUN and CMD execute commands, but their timing and purpose differ:
RUN: Build-time command
The RUN instruction:
Executes commands during the image build process.
Creates a new layer in the image.
Example:
# Dockerfile
RUN apt-get update && apt-get install -y python3
- RUN installs Python during image build, making it available in the final image.
CMD: Runtime command
The CMD instruction:
Specifies the default command to execute when the container starts.
Does not persist in the image.
Example:
# Dockerfile
CMD ["python3", "app.py"]
- Running
docker run <image>→ Executespython3 app.pywhen the container starts.
When to use RUN vs CMD?
Use RUN for tasks that configure or install software during the build.
Use CMD to specify the container’s runtime behavior.
4. Summary
| Instruction | Purpose | Execution Time | Overridable? | Common Use Cases |
| ADD | Copies files/directories and extracts tar archives | Build time | No | Download files or extract archives. |
| COPY | Copies files/directories | Build time | No | Simple file copying. |
| CMD | Specifies default runtime command | Container runtime | Yes | Setting default commands for containers. |
| ENTRYPOINT | Sets fixed runtime executable | Container runtime | Partially (arguments can be appended) | Defining the main process of a container. |
| RUN | Executes commands to build image | Build time | No | Installing software, configuring images. |
5. Full Example: Putting It All Together
Here’s a complete Dockerfile demonstrating these instructions in action:
FROM ubuntu
# Use RUN to install software during build time
RUN apt-get update && apt-get install -y curl
# Use ADD to extract a tar file
ADD data.tar.gz /app
# Use COPY to copy a config file
COPY config.json /app/config.json
# Use ENTRYPOINT for a fixed command
ENTRYPOINT ["echo"]
# Use CMD to provide default arguments
CMD ["Hello from CMD!"]
How This Works:
During Build:
RUNinstallscurlinto the image.ADDextractsdata.tar.gzinto/app.COPYplacesconfig.jsoninto/app.
At Runtime:
Running
docker run <image>→ Outputs:Hello from CMD!.Running
docker run <image> Goodbye→ Outputs:Goodbye.
Key Takeaways
ADD is powerful but unpredictable; prefer COPY unless you need its extra features.
CMD provides default behavior, while ENTRYPOINT sets a fixed process.
RUN is for build-time tasks; CMD defines runtime behavior.
By mastering these instructions, you can create clean, efficient Dockerfiles that are easy to maintain. Happy Dockering! 🛥️


