Dockerfile Keywords Explained & Interview Nuggets 🐳
A deep dive into Dockerfile directives, build vs. runtime mechanics, caching performance, security guardrails, and must-know interview trade-offs.
Published by AHP • cicdclouds.com
1. Image Inception & Metadata Directives
A Dockerfile is a declarative script containing step-by-step instructions that the Docker daemon evaluates sequentially to construct an immutable container image. Every build context begins by establishing a lineage and metadata identity.
1. FROM — Base Image Definition
- Defines the primary foundational platform or operating system layer for the build stage.
- Every valid
Dockerfilemust start with aFROMinstruction (the only exception being an initialARGused to set variable base image tags). - For bare-metal or scratch builds with zero overhead (e.g., static Go/Rust binaries), use
FROM scratch.
# Syntax example
FROM ubuntu:22.04 AS base-environment
2. MAINTAINER (Deprecated)
- Historically assigned the author or operational contact details for the image.
- Modern Practice: Fully superseded by the generic
LABELdirective for key-value flexibility.
# Deprecated syntax:
# MAINTAINER devops@cicdclouds.com
# Modern standard:
LABEL maintainer="devops@cicdclouds.com"
3. LABEL — Object Metadata
- Appends structured metadata, versioning tags, team ownership, and architectural details to the final image inspection record.
- Labels are accessible via
docker inspectand can be queried programmatically across automated CI/CD registries.
LABEL version="2.4.0" \
description="Production API Gateway" \
environment="production" \
team="PlatformOps"
2. Build-Time Processing & Filesystem Population
These directives manipulate files and run OS-level commands strictly during image compilation (docker build), committing intermediary read-only filesystem layers.
4. RUN — Build-Time Execution
- Executes system-level commands, runs package managers, creates directories, and alters the target image state.
- Each
RUNstatement creates an intermediate cacheable layer. Always chain related commands with&&and clean package caches within the same layer to minimize total image size.
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
5. COPY — Host-to-Container Ingestion
- Transfers files or directories directly from the local build context on the host machine into the image filesystem.
- Provides a transparent, deterministic copy mechanism with support for user ownership flags (
--chown).
COPY --chown=appuser:appgroup ./config.yaml /app/config.yaml
6. ADD — Advanced Ingestion & Extraction
- Performs host-to-image file copying similar to
COPY, but brings two specialized automation features:- Automatic Archive Extraction: Unpacks local tar archives (
.tar,.tar.gz,.tgz) directly into destination image folders. - Remote URL Downloads: Retrieves files straight from remote HTTP/HTTPS endpoints into the container layer.
- Automatic Archive Extraction: Unpacks local tar archives (
# Extracts archive into /opt/bin/
ADD application-dist.tar.gz /opt/bin/
⚡ Interview Goldmine:
COPYvs.ADDRule of ThumbAlways default to
COPYfor local files and project dependencies.COPYis explicit, transparent, and avoids unexpected tar auto-extraction or hidden security vulnerabilities. ReserveADDexclusively when native archive extraction is explicitly intended.
3. Variables, Scoping & Shell Configuration
7. ARG — Build-Time Parameters
- Defines variables passed into the build process using
--build-arg <varname>=<value>. - Ephemeral: Does not persist into running containers or the final inspected image environment.
ARG APP_VERSION=1.0.0
RUN echo "Compiling binaries for release v${APP_VERSION}"
8. ENV — Runtime Environment Variables
- Sets environment variables that persist both during build layers and across the container's operational lifetime at runtime.
- Variables set by
ENVare inheritable by children processes and inspectable viadocker exec -it <container> env.
ENV APP_PORT=8080 \
APP_ENV=production \
LOG_LEVEL=warn
9. SHELL — Default Execution Interpreter
- Changes the default shell executable and flags used by subsequent
RUNcommands in the Dockerfile. - Default Linux shell is
["/bin/sh", "-c"]. Overriding to bash enables flags likepipefailfor safer scripting.
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
4. Port Declarations, Volumes & Security Hardening
10. EXPOSE — Network Port Documentation
- Declares the intended incoming network ports the containerized service listens on.
- Informational:
EXPOSEacts as documentation between image builders and operators; it does not open the ports to the host machine unless mapped via-por-Pat runtime.
EXPOSE 8080 8443
11. USER — Least Privilege Enforcement
- Defines the UID/GID or username running subsequent build instructions and the final container runtime process.
- Production Security Standard: Never run container workloads as
root. Always declare and switch to a non-privileged user to contain potential privilege escalation attacks.
RUN groupadd -r appgroup && useradd -r -g appgroup -u 10001 appuser
USER appuser
12. VOLUME — Persistent & Shared Storage Points
- Declares an externally managed mount point inside the container image.
- Anything written to a
VOLUMEpath bypasses the temporary copy-on-write (CoW) container storage layer, ensuring persistent storage management and high I/O throughput.
VOLUME ["/var/log/app", "/data/storage"]
13. STOPSIGNAL — Graceful Termination Signals
- Configures the exact system call interrupt signal sent to the container process when issuing
docker stop(default isSIGTERM). - Essential for services like NGINX (
SIGQUIT) to finish active client sessions before closing sockets.
STOPSIGNAL SIGQUIT
5. Runtime Process Initialization: CMD vs. ENTRYPOINT
Determining how a container launches its primary process (PID 1) is one of the most frequently asked concepts in DevOps technical evaluations.
14. CMD — Default Command or Arguments
- Supplies default parameters or a default fallback command for a container.
- Easily overridden by passing arbitrary arguments at the end of the runtime command:
docker run <image> <override-command>.
CMD ["python3", "server.py"]
15. ENTRYPOINT — The Fixed Binary / Executable
- Configures a permanent executable target that container invocations run against.
- Cannot be overridden simply by appending CLI arguments (requires the explicit
--entrypointflag).
ENTRYPOINT ["python3", "server.py"]
The Recommended Synergy: Executable + Default Argument
Industry-standard microservice design pairs ENTRYPOINT as the non-negotiable executable and CMD as the overridable default arguments:
# Container behaves like an executable binary CLI tool
ENTRYPOINT ["python3"]
CMD ["app.py"]
Running docker run my-python-app defaults to executing python3 app.py. Passing custom arguments like docker run my-python-app test.py dynamically executes python3 test.py without breaking the wrapper!
6. ⚡ Quick Interview Comparison Tables
Keep these architectural distinctions top of mind for cloud and platform engineering interviews.
Comparison Matrix 1: COPY vs. ADD
| Feature / Property | COPY |
ADD |
|---|---|---|
| Local Filesystem Copying | ✅ Yes (Host to container) | ✅ Yes (Host to container) |
| Tar Auto-Extraction | ❌ No (Copies archive as-is) | ✅ Yes (Automatically decompresses recognized archives) |
| Remote URL Download | ❌ No | ✅ Yes (Downloads remote files into layer) |
| Build Cache Predictability | High (Strict file checksum verification) | Moderate (Remote file changes can invalidate cache unexpectedly) |
| DevOps Best Practice | Preferred Standard for all standard app assets | Restricted strictly to automatic compressed tar extractions |
Comparison Matrix 2: CMD vs. ENTRYPOINT
| Feature / Property | CMD |
ENTRYPOINT |
|---|---|---|
| Core Purpose | Provides overridable defaults for the container. | Defines the fixed, immutable executable (PID 1). |
| CLI Argument Override | Effortless: Directly superseded by any CLI argument passed to docker run. |
Strict: CLI arguments are appended as positional parameters to the executable. |
| Hard Override Mechanism | docker run <image> <new-cmd> |
Requires explicit flag: docker run --entrypoint <new-bin> <image> |
| CLI Tool Behavior | Acts like an arbitrary task runner or script. | Transforms the container into a self-contained executable utility. |
Comparison Matrix 3: ARG vs. ENV
| Aspect | ARG |
ENV |
|---|---|---|
| Scope Lifetime | Build-time only (during docker build). |
Build-time AND Runtime (during docker run). |
| Persistence in Image | ❌ No (Discarded after image layers compile). | ✅ Yes (Persists across all derived containers). |
| Runtime Modification | N/A (Unavailable at runtime). | Overridable via docker run -e KEY=VAL. |
| Typical Use Cases | Specifying package versions, build tokens, and compilation flags. | Database endpoints, port configurations, and application profiles. |