Building Docker Images
Writing Your First Dockerfile — Every Instruction Explained
FROM, RUN, COPY, ADD, CMD, ENTRYPOINT, and ENV rules.
Interview: Highly relevant for DevOps, SRE, and cloud developer roles. Expect detailed questions on CMD vs ENTRYPOINT, COPY vs ADD, and exec form vs shell form.
Introduction
A container image is built using a recipe file called a Dockerfile. A Dockerfile is a plaintext configuration script containing sequential instructions that the Docker daemon executes to assemble an image.
Each instruction represents a command (like copying code, compiling dependencies, or exposing ports) and creates an underlying filesystem layer.
Why It Matters
Writing Dockerfiles correctly determines image size, security vulnerability counts, cache utilization speeds, and whether processes terminate gracefully in cloud environments.
Core Instruction Reference
Below is a guide to the primary directives used in Dockerfiles:
| Instruction | Purpose | Usage Rule |
|---|---|---|
| FROM | Defines the parent base image. | Must be the very first instruction (e.g., FROM python:3.11-slim). |
| WORKDIR | Sets the active directory inside the container. | Avoids using raw path CD commands. Creates the folder if missing. |
| RUN | Executes commands inside the image during build time. | Creates a new layer. Commonly used for installing packages. |
| COPY | Copies files from the host to the image. | Preferred for local directory transfers. |
| ADD | Copies files, downloads URLs, and unpacks tars. | Only use when tar auto-extraction or URL download is explicitly needed. |
| ENV | Defines persistent environment variables. | Available both during image build and container runtime. |
| ARG | Defines transient build arguments. | Only available during image compilation; not at runtime. |
CMD vs ENTRYPOINT
These two commands specify the execution entrypoint of a container, but they behave differently:
• ENTRYPOINT: Defines the executable command. It is not overridden when running a container with arguments.
• CMD: Defines the default parameters or fallback command. It is completely overridden if custom arguments are passed to the CLI.
Cooperative Behavior: If you use them together, ENTRYPOINT acts as the binary, and CMD acts as the default arguments:
Running docker run my-image executes ping localhost.
Running docker run my-image google.com overrides CMD, executing ping google.com.
Practical Example
Here is a complete Dockerfile for a Python web application, demonstrating proper instruction declarations:
Quick Quiz
Q1: What is the main difference between COPY and ADD?
A) COPY is for files and ADD is for directories.
B) COPY is the modern standard for basic file copy. ADD does the same but supports auto-extracting tar archives and downloading remote URLs.
C) ADD runs during runtime, COPY during build time.
D) There is no difference.
Answer: B — COPY is preferred for simplicity unless you need the URL fetch or tar auto-unpack features of ADD.
Scenario-Based Challenge
Production Scenario:
You configure your container entrypoint using the shell form: ENTRYPOINT my-app.sh. When you run docker stop, the container takes 10 seconds to terminate and is terminated forcefully via SIGKILL. Why did it ignore the SIGTERM signal, and how do you resolve it?
Cause: Using the shell form (ENTRYPOINT command) wraps your executable inside /bin/sh -c. Consequently, the shell runs as PID 1, and your application script runs as a child process. Linux shells do not propagate OS signals to child processes by default. Your application never receives the SIGTERM signal sent by docker stop, leading Docker to wait 10 seconds before killing the process forcefully with SIGKILL.
Solution: Rewrite the entrypoint using the **Exec Form** (JSON array):
ENTRYPOINT ["/bin/sh", "my-app.sh"] or directly ENTRYPOINT ["./my-app.sh"].
This runs your script directly as PID 1, allowing it to receive and handle termination signals immediately.
Interview Questions
1. Explain the differences between RUN and CMD.
RUN executes commands during the **build phase** to compile libraries or packages, creating a new image layer. CMD specifies the default executable or arguments that run when the container **starts up at runtime**; it does not compile anything.
2. What is the difference between ENV and ARG?
ARG values are only available during the build phase of the image and do not persist in the final image binary. ENV variables are baked into the image metadata and persist into the running container environment.
Production Considerations
In production, always lock down your base image tag version (e.g., use FROM node:20.11.0-alpine instead of FROM node:latest). This prevents build pipelines from breaking when new node versions are pushed, ensuring build reproducibility and security auditing consistency.