Skip to main content

Command Palette

Search for a command to run...

🐳 Dockerfile Deep Dive - Day 3: Commands, Working & Industry Example

Building Efficient Images Step by Step

Published
4 min read
🐳 Dockerfile Deep Dive - Day 3: Commands, Working & Industry Example
A

Cloud & DevOps enthusiast learning in public ☁️⚙️ Documenting my journey through systems, automation, and real-world engineering problems. Focused on fundamentals, practical learning, and continuous growth.

In Day 1 and Day 2, we understood containers and Docker fundamentals.
In this part, we’ll focus on the Dockerfile — the heart of every Docker image — and see how it works internally, its key commands, and how Dockerfiles are written in real production environments.


📄 What is a Dockerfile?

A Dockerfile is a plain text file that contains a set of instructions used by Docker to build an image.

Each instruction in a Dockerfile:

  • Executes top to bottom

  • Creates a new image layer

  • Can be cached to speed up future builds

Dockerfiles make application builds:

  • Repeatable

  • Version-controlled

  • Portable across environments

📷 Dockerfile → Docker Container

What Is Dockerfile Extension ? - GeeksforGeeks


🔄 How a Dockerfile Works (Internal Flow)

When Docker builds an image, it follows a simple process:

  1. Docker reads the Dockerfile line by line

  2. Each instruction runs inside a temporary container

  3. Changes are committed as a new image layer

  4. The final image is produced

If a layer hasn’t changed, Docker reuses cached layers, making builds much faster.


🧩 Common Dockerfile Instructions (Must-Know Commands)

1️⃣ FROM

FROM ubuntu:22.04
  • Defines the base image

  • Must be the first instruction (except ARG)

  • Every image starts from another image

📌 Example:

FROM python:3.11-slim

2️⃣ LABEL

LABEL maintainer="devops@company.com"
  • Adds metadata like owner, version, or description

3️⃣ RUN

RUN apt-get update && apt-get install -y nginx
  • Executes commands during image build

  • Creates a new image layer

✅ Best practice:

RUN apt-get update \
 && apt-get install -y nginx \
 && rm -rf /var/lib/apt/lists/*

4️⃣ WORKDIR

WORKDIR /app
  • Sets the working directory inside the container

  • Avoids repeated cd commands

  • Creates the directory if it doesn’t exist


5️⃣ COPY

COPY . /app
  • Copies files from host to container

  • Preferred over ADD for clarity


6️⃣ ADD

ADD app.tar.gz /app
  • Similar to COPY

  • Supports extracting tar files and remote URLs

⚠️ Best practice: Use COPY unless ADD features are required.


7️⃣ ENV

ENV APP_ENV=production
  • Sets environment variables

  • Available at runtime


8️⃣ ARG

ARG VERSION=1.0
  • Build-time variables

  • Not available inside running containers

  • Commonly used for versioning and configs


9️⃣ EXPOSE

EXPOSE 8080
  • Documents which port the app uses

  • Does not publish the port automatically


🔟 CMD

CMD ["node", "server.js"]
  • Defines the default command

  • Can be overridden at runtime

  • Only the last CMD is effective


1️⃣1️⃣ ENTRYPOINT

ENTRYPOINT ["python3", "app.py"]
  • Defines the main executable

  • Harder to override

CMD vs ENTRYPOINT (Very Important)

FeatureCMDENTRYPOINT
PurposeDefault argsMain process
OverrideYesNo (without flag)
Use caseOptional paramsFixed app

✅ Best practice:

ENTRYPOINT ["python3", "app.py"]
CMD ["--help"]

1️⃣2️⃣ VOLUME

VOLUME /data
  • Creates a mount point

  • Used for persistent data


1️⃣3️⃣ USER

USER appuser
  • Runs container as non-root

  • Improves security


1️⃣4️⃣ HEALTHCHECK

HEALTHCHECK CMD curl --fail http://localhost:8080 || exit 1
  • Monitors container health

  • Widely used in production and Kubernetes


1️⃣5️⃣ STOPSIGNAL

STOPSIGNAL SIGTERM
  • Defines graceful shutdown behavior

1️⃣6️⃣ ONBUILD

ONBUILD COPY . /app
  • Executes when the image is used as a base image

  • Common in framework base images


🏭 Dockerfile Best Practices (Industry)

Production-grade Dockerfiles usually follow these rules:

  • Use slim base images

  • Combine RUN commands

  • Use .dockerignore

  • Avoid secrets in Dockerfile

  • Run containers as non-root

  • Use multi-stage builds


🏗️ Industrial Dockerfile Example (Production Ready)

Example: Python FastAPI Application

# ---------- Stage 1: Build ----------
FROM python:3.11-slim AS builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# ---------- Stage 2: Runtime ----------
FROM python:3.11-slim

LABEL maintainer="devops@company.com"
LABEL app="fastapi-app"

WORKDIR /app

COPY --from=builder /usr/local/lib/python3.11 /usr/local/lib/python3.11
COPY --from=builder /usr/local/bin /usr/local/bin
COPY . .

ENV APP_ENV=production
ENV PYTHONUNBUFFERED=1

EXPOSE 8000

USER nobody

ENTRYPOINT ["uvicorn"]
CMD ["main:app", "--host", "0.0.0.0", "--port", "8000"]

The Dockerfile above demonstrates a production-ready, multi-stage build for a Python FastAPI application.

Note: The next blog will cover multi-stage Dockerfiles in detail, including how each stage works, why it’s used, and best practices.
This example is provided for reference only so you can see what a real-world Dockerfile looks like.


✅ Why This Dockerfile Is Industry Standard

  • Multi-stage build reduces image size

  • No unnecessary build tools in final image

  • Runs as non-root user

  • Uses slim base image

  • Clear ENTRYPOINT + CMD usage

  • Fully production-ready

Docker Simplified: A Beginner's Guide

Part 3 of 10

A beginner-friendly Docker series covering core concepts, architecture, hands-on examples, Dockerfiles, images, containers, and real-world usage — explained in simple terms.

Up next

🐳 Docker – Day 4 : Multi-Stage & Distroless Image

Building Secure, Lightweight, Production-Ready Images