Comprehensive Dockerfile Reference & Advanced Mechanics
Published on
Dockerfile Advanced Deep Dive
1. Meta-Configuration (The “Brain Upgrade”)
Dockerfiles have a hidden mode at the very top (Line 1). These are Parser Directives, not comments.
The Syntax Directive
# syntax=docker/dockerfile:1
This acts like a software update for the Docker builder.
Benefits:
- Unlocks modern Dockerfile features.
- Allows usage of new syntax even on older Docker versions.
- Required to use BuildKit optimizations and Here-Docs.
2. Variable Mastery: ARG vs ENV (Ghosts vs Zombies)
Mixing ARG and ENV is a classic way to create weird, fragile builds.
| Feature | Nickname | Lifetime | Scope | Best For |
|---|---|---|---|---|
| ARG | Ghost 👻 | Build-time only | Layer-specific | Versions, build flags |
| ENV | Zombie 🧟 | Runtime | Whole container | App config, ports, URLs |
Pro Tip 1: The “Spare Tire” Default Syntax
ENV PORT=${BUILD_PORT:-8080}
If BUILD_PORT is undefined, Docker automatically uses 8080.
Pro Tip 2: The ARG Scoping Trap
ARG before FROM is visible to FROM, but not to later build steps unless you re-declare it.
ARG VERSION=latest
FROM alpine:$VERSION
ARG VERSION
RUN echo $VERSION
If you forget the second ARG VERSION, RUN echo $VERSION prints nothing.
3. Advanced File Operations
Rule: Default to COPY. Only use ADD when you explicitly need its “superpowers”.
ADD vs COPY
| Command | Superpowers |
|---|---|
| COPY | Simple, explicit, predictable caching |
| ADD | Remote URL download + auto-extract tar/zip archives |
The “Here-Doc” (Inline File Creation)
Write config files directly in the Dockerfile:
COPY <<EOF /app/config.txt
User=Admin
Mode=Production
EOF
No separate config file needed in the build context.
4. BuildKit Optimization: Cache Mounts
The Problem
By default, Docker forgets everything between builds and re-downloads package indexes every time:
apkaptpipetc.
The Solution
Use BuildKit’s cache mounts.
Alpine example:
RUN --mount=type=cache,target=/var/cache/apk,sharing=locked \
apk update && \
apk add curl
Rules:
--mount=...goes immediately afterRUN.targetmust be the package manager’s cache dir.- Use
&&soapk addonly runs ifapk updatesucceeds.
5. Runtime Control: Executables
Make the container behave like a single-purpose binary.
ENTRYPOINT→ The command.CMD→ Default arguments (overridable atdocker run).
ENTRYPOINT ["curl"]
CMD ["https://google.com"]
Running the container is now basically like running curl https://google.com.
6. The Exec Form Trap (Critical)
Shell form vs exec form:
CMD echo $HOME
- Goes through a shell.
$HOMEexpands correctly. ✅
CMD ["echo", "$HOME"]
- No shell → no variable expansion.
- Prints the literal string
$HOME. ❌
Golden Rule:
If you need dynamic environment variables at runtime, use:
- Shell form, or
- A small shell script as your
ENTRYPOINT, and keepCMDas plain arguments.
By – Chinmay Bagad
Thank you for reading. This article is part of the PaperAstro starter template.