Skip to main content
PacketMentor logo
Open menu
← All topics
Automation & Programmability Foundational

Dockerfile Explained Line by Line

Every Dockerfile instruction you need for CCNAAUTO 200-901 4.6: FROM, WORKDIR, COPY, RUN, EXPOSE, ENV, CMD and ENTRYPOINT. A tiny Python app in one Dockerfile, line by line.

Quick summary
  • A Dockerfile is a recipe. docker build reads it top to bottom, running each instruction in order and saving a layer per step.
  • The 7 instructions you must know: FROM, WORKDIR, COPY, RUN, EXPOSE, ENV, CMD.
  • Each line adds a layer. Combine RUN steps with && to keep images small. Order lines from least-to-most changeable so cache survives.

Mental model

A Dockerfile is a plain text recipe. docker build reads it top-to-bottom, running each instruction, saving a filesystem layer after each. The result is a reusable image you can docker run.

Cisco objective 4.6 says “Interpret contents of a Dockerfile”. You need to read a Dockerfile and explain what each line does.

The example

A Python Flask web app in 9 lines.

FROM python:3.11-slim

WORKDIR /app

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

COPY app.py .

EXPOSE 5000
ENV FLASK_APP=app.py

CMD ["flask", "run", "--host=0.0.0.0"]

Line by line

FROM python:3.11-slim

Every Dockerfile starts with FROM. It names a base image. Here, the official Python 3.11 slim image (small Debian + Python + pip). Subsequent instructions add on top of it.

WORKDIR /app

Sets the working directory for the rest of the Dockerfile. Any later COPY, RUN, CMD happens relative to /app. Creates the directory if it does not exist.

COPY requirements.txt .

Copies requirements.txt from the build context (the directory you ran docker build from) into /app/. on the image. The . here means “the current WORKDIR”.

RUN pip install --no-cache-dir -r requirements.txt

Runs a command during build. The output of this command becomes part of the next layer. --no-cache-dir keeps the layer small by not caching downloaded wheels.

COPY app.py .

Second COPY. Deliberately after requirements install: pip install is slow and does not change often. If only app.py changes, the earlier layer cache stays valid.

EXPOSE 5000

Documents which port the container listens on. Does not actually open the port at run time (you still need -p 5000:5000 on docker run); it is a hint to humans and tools.

ENV FLASK_APP=app.py

Sets an environment variable visible to the running process.

CMD ["flask", "run", "--host=0.0.0.0"]

The command to run when a container starts. CMD can be overridden by docker run ... <different command>. Prefer the JSON-array form (["cmd", "arg1", "arg2"]) to avoid shell parsing surprises.

The 10 instructions worth knowing

InstructionPurpose
FROMBase image. Required.
WORKDIRSet the working directory for subsequent instructions.
COPY <src> <dst>Copy from build context into image.
ADD <src> <dst>Like COPY but also extracts tarballs and fetches URLs. Prefer COPY unless you need those extras.
RUN <cmd>Execute a command during build.
ENV KEY=valueSet an env var in the image (persists at runtime too).
EXPOSE <port>Document the port.
CMD ["x", "y"]Default command when a container starts. Overridable.
ENTRYPOINT ["x"]Fixed command; CMD becomes its default arguments.
USER <name>Run subsequent instructions / the final process as this user. Good security hygiene.

CMD vs ENTRYPOINT

  • CMD is a suggestion. docker run myimage echo hello replaces the CMD.
  • ENTRYPOINT is a fix. docker run myimage echo hello becomes <entrypoint> echo hello with echo being arguments.

Common pattern:

ENTRYPOINT ["python", "-m"]
CMD ["myapp"]

Default run: python -m myapp. Override: docker run myimage pytest becomes python -m pytest.

Layer caching

Docker caches each instruction’s output. If you change line 7, lines 1 to 6 are reused instantly. Rule:

  • Instructions that change rarely go first (base image, system deps).
  • Instructions that change often go last (your application code).

A common blunder: COPY . . on line 2. Any file change invalidates everything after it, including the slow pip install.

The .dockerignore file

Alongside the Dockerfile. Lists files to EXCLUDE from the build context. Keeps secrets (.env, .aws/credentials) and junk (node_modules, __pycache__) out of your image.

# .dockerignore
.git
.env
__pycache__
*.pyc
node_modules

Building and running

docker build -t myapp:1.0 .           # . = build context (current dir)
docker run -d -p 5000:5000 myapp:1.0

See the docker run / pull topic for the full image / container workflow.

Hands-on lab · 6 minute walkthrough

Build an image, run a container, tear it down

12 steps: pull, run, ps, logs, exec, stop, rm, build from a tiny Dockerfile. Real engine; images and containers tracked across the whole session.

Open the lab →
docker-basics · lab
you@laptop:~$ docker pull nginx
Status: Downloaded newer image for nginx:latest
you@laptop:~$ docker run -d --name web nginx
you@laptop:~$

FAQ

Does the order of lines matter? Yes. Instructions that invalidate cache (COPY .) should come as late as possible. Order from least-changing to most-changing.

Can I have more than one FROM in a Dockerfile? Yes — a multi-stage build. First stage compiles with a big SDK image; final stage copies just the binary into a tiny runtime image. Not called out directly in 200-901.

Where does COPY . . copy from? The build context — the directory passed to docker build. If you ran docker build -t app ., the context is the current directory. Everything (minus .dockerignore) is sent to the Docker daemon.

What happens if I omit CMD? If the base image has one (most do), you inherit it. If neither has one, docker run fails because there is nothing to run.

Master this on a real network

Want this drilled into reflex?

1:1 weekly sessions, live feedback on your labs, and US interview prep: built around the CCNA Automation® exam blueprint. Free first session. No card on file until you decide.

Claim my free session →

Get the free CCNA 12-week roadmap

You're already reading up on Dockerfile Explained Line by Line. The roadmap is the order I recommend studying every CCNA topic in: with what to lab each week and where Dockerfile Explained Line by Line fits. A written personal reply, not an autoresponder. Expect it within one business day.

Personal reply from a senior network engineer. No third-party tracking. Unsubscribe any time.