Home / Docker & Containers
DevOps & Containerization Guide

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 Dockerfile must start with a FROM instruction (the only exception being an initial ARG used 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 LABEL directive 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 inspect and 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 RUN statement 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:
    1. Automatic Archive Extraction: Unpacks local tar archives (.tar, .tar.gz, .tgz) directly into destination image folders.
    2. Remote URL Downloads: Retrieves files straight from remote HTTP/HTTPS endpoints into the container layer.
# Extracts archive into /opt/bin/
ADD application-dist.tar.gz /opt/bin/

⚡ Interview Goldmine: COPY vs. ADD Rule of Thumb

Always default to COPY for local files and project dependencies. COPY is explicit, transparent, and avoids unexpected tar auto-extraction or hidden security vulnerabilities. Reserve ADD exclusively 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 ENV are inheritable by children processes and inspectable via docker 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 RUN commands in the Dockerfile.
  • Default Linux shell is ["/bin/sh", "-c"]. Overriding to bash enables flags like pipefail for 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: EXPOSE acts as documentation between image builders and operators; it does not open the ports to the host machine unless mapped via -p or -P at 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 VOLUME path 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 is SIGTERM).
  • 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 --entrypoint flag).
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.