Dockerfile#
A Dockerfile contains two completely different types of instructions: those that build the filesystem layers (the heavy lifting) and those that update the metadata/manifest (the instructions for the runtime).
Here is how the commands map to those two concepts:
Layer Instructions
These commands actually change the files on the disk. Every time you run one of these, the builder takes a snapshot of the filesystem, calculates the difference (diff), and saves it as a new Layer (a compressed tarball).
FROM ubuntu:20.04Starts with the base layer.COPY . /appAdds files from your laptop. Creates a new layer containing just those files.RUN apt-get install pythonRuns a command, sees what files changed, and saves those changes as a new layer.
Result: These create the physical “blobs” that take up space (MB or GB) in your registry.
Manifest/Metadata Instructions:
These commands do not create layers or add any file size. They simply update the Image Configuration (which ends up in the Manifest). They are notes passed to the container engine (like Kubernetes or Docker) on how to use the image.
EXPOSE 80Writes to the config: “Whoever runs this, know that I intend to listen on port 80.” (It doesn’t actually open the port; it just documents it).CMD ["python", "app.py"]Writes to the config: “If the user doesn’t say otherwise, run this command when starting.”ENV APP_VERSION=1.0Writes to the config: “Set this variable in the process environment.”WORKDIR /appWrites to the config: “Start the user in this directory.”USER 1001Writes to the config: “Switch to user ID 1001 before running anything.”
Result: These add 0 bytes to the image size. They just edit a small JSON file (the Config) that accompanies the layers.
Summary:
Dockerfile Instruction |
Type |
Effect on Image |
Where it lives |
|---|---|---|---|
|
Builder |
Adds 50MB |
In a Layer (tar.gz) |
|
Declarative |
Adds 0 bytes |
In the Manifest/Config (JSON) |
|
Builder |
Adds 2MB |
In a Layer (tar.gz) |
|
Declarative |
Adds 0 bytes |
In the Manifest/Config (JSON) |
So, when you write a Dockerfile, you are simultaneously scripting the construction of the filesystem (Layers) and the configuration of the runtime environment (Manifest).