Docker module
Lesson 7
Write a Dockerfile
FROM, COPY, RUN, CMD, docker build, and why you do not bake secrets into an image.
beginner35 minRun on your machine
What you will be able to do
- Write a small Dockerfile that copies a script and sets CMD
- Build a tagged image and run it
- Explain why passwords do not belong in Dockerfile lines
Why this matters for DE and AI
A job image is a Dockerfile: start from a base, copy extract.sh (or later Python), set the command. If the recipe is missing a file, every cluster that pulls the image is missing it too. Building locally is how you find that before a scheduler does.
Concepts
A Dockerfile is a list of instructions. We will use four:
| Instruction | Meaning |
|---|---|
FROM alpine:3.20 |
Start from this image |
WORKDIR /app |
Create/set the working directory |
COPY greet.sh /app/greet.sh |
Copy from the build context (usually .) into the image |
RUN chmod +x /app/greet.sh |
Run a command at build time (layers the result) |
CMD ["/app/greet.sh"] |
Default command when someone docker runs |
CMD vs command on docker run: if you pass a command after the image name, it replaces CMD.
Build context is the directory you pass to docker build. COPY can only see files inside it. That is why we build from a small folder, not from $HOME.
docker build -t dcubes-hello:1 .
-t tags the result. . is the context (the directory with the Dockerfile).
.dockerignore is a list of names not to send in the context (like .gitignore). Optional for this tiny lab; required later when the folder has data files you do not want in the image.
Practice on your machine
mkdir -p ~/dcubes/docker-lab/hello
cd ~/dcubes/docker-lab/hello
Write a script the image will run:
cat > greet.sh << 'EOF'
#!/bin/sh
echo "hello from a dcubes image"
echo "time: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
EOF
Write the Dockerfile (filename has no extension):
cat > Dockerfile << 'EOF'
FROM alpine:3.20
WORKDIR /app
COPY greet.sh /app/greet.sh
RUN chmod +x /app/greet.sh
CMD ["/app/greet.sh"]
EOF
Build:
docker build -t dcubes-hello:1 .
What you should see: steps for FROM, WORKDIR, COPY, RUN, CMD. Docker caches steps; a second build is nearly instant if nothing changed.
docker images dcubes-hello
docker run --rm dcubes-hello:1
What you should see: repository dcubes-hello, tag 1, then two lines of greeting and a UTC timestamp.
Override CMD once, to prove you can:
docker run --rm dcubes-hello:1 cat /app/greet.sh
That prints the script instead of running it.
Change the echo line in greet.sh, rebuild with the same tag, and run again. You should see the new text. Same tag, new image ID — tags move locally too when you rebuild.
Common mistakes
- Building from the wrong directory.
COPY greet.shfails if you are indocker-laband the file is inhello/.cdintohello(or pass-fand a context path). - Forgetting
chmod +x.CMDthen fails with permission denied. - Using
ADDinstead ofCOPY.ADDcan extract archives and fetch URLs. PreferCOPYunless you have a reason.
Next
Persist data — bind mounts and named volumes so files survive rm.