Dockerfile basics
A Dockerfile is a recipe. Every step becomes a layer, and CMD decides what runs when the container starts.
key idea / Docker itselfcontainer / good pathhost / watch outproblem / blockedneutral
From recipe to layers
Docker executes the file top to bottom and saves the result of each step as a layer.
Build time versus run time
The confusion between RUN and CMD disappears once you separate the two moments.
The instructions you will use daily
| Instruction | Job | Can be replaced by docker run image ...? |
|---|---|---|
RUN | runs at build time, adds a layer | no, already baked in |
CMD | default command at start | yes: whatever you type replaces it |
ENTRYPOINT | fixed program at start | no, your words become its arguments |
COPY | host files into the image | no (use -v for runtime files) |
ADD | COPY plus URLs and tar extract | prefer COPY; ADD surprises people |
Try it yourself
Work in an empty directory. Each instruction below becomes one layer.
-
Step 1 · Write the files
$ mkdir greet && cd greet $ printf 'hello from the image\n' > hello.txt $ cat > Dockerfile << 'EOF' FROM alpine:3.20 WORKDIR /app COPY hello.txt . RUN printf 'built in the image\n' > /app/built.txt CMD ["cat", "/app/hello.txt"] EOF -
Step 2 · Build, and read each step
The numbers are the Dockerfile instructions.
FROMdownloads Alpine.WORKDIRcreates/app.COPYaddshello.txt.RUNwritesbuilt.txtinto the image.$ docker build -t greet:1 . [1/4] FROM docker.io/library/alpine:3.20 [2/4] WORKDIR /app [3/4] COPY hello.txt . [4/4] RUN printf 'built in the image\n' > /app/built.txt naming to docker.io/library/greet:1 -
Step 3 · CMD is the default process
$ docker run --rm greet:1 hello from the image -
Step 4 · A command on docker run replaces CMD
The file from
RUNis in the image, so this container can read it.--rmdeletes the container whencatexits. The image stays.$ docker run --rm greet:1 cat /app/built.txt built in the image $ docker images greet REPOSITORY TAG IMAGE ID SIZE greet 1 9f0c1a2b3c4d 8MB
Recap
- Each
FROM,COPY,RUNcreates a layer;CMDadds only metadata. RUNruns at build time.CMDruns when a container starts.CMDis a replaceable default;ENTRYPOINTis the fixed program.- Prefer
COPYoverADD, and a small pinned base likealpine.
Quick check
CMD lines. What runs?Show answer
Only the last one. Earlier CMD lines are ignored. Use ENTRYPOINT when the command must not be replaced by arguments.