Understanding Image Layers
Docker images are built using a layered filesystem. Each layer represents a set of filesystem changes. This layered approach allows Docker to be efficient with storage and network usage. Let's explore this concept.
First, let's inspect the layers of the Nginx image we pulled earlier:
docker inspect --format='{{.RootFS.Layers}}' nginx
You'll see output similar to this:
[sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f sha256:e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8 sha256:b5357ce95c68acd9c9672ec76e3b2a2ff3f8f62a2bcc1866b8811572f4d409af]
Each of these long strings (called SHA256 hashes) represents a layer in the image. Each layer corresponds to a command in the Dockerfile used to build the image.
To better understand layers, let's create a simple custom image. First, create a new file named Dockerfile
in your current directory:
nano Dockerfile
In this file, add the following content:
FROM nginx
RUN echo "Hello from custom layer" > /usr/share/nginx/html/hello.html
This Dockerfile does two things:
- It starts with the Nginx image we pulled earlier (
FROM nginx
)
- It adds a new file to the image (
RUN echo...
)
Save and exit the file (in nano, you can do this by pressing Ctrl+X, then Y, then Enter).
Now let's build this image:
docker build -t custom-nginx .
Sample output:
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM nginx
---> 5ef79149e0ec
Step 2/2 : RUN echo "Hello from custom layer" > /usr/share/nginx/html/hello.html
---> Running in 2fa43e649234
Removing intermediate container 2fa43e649234
---> 73b62663b5c3
Successfully built 73b62663b5c3
Successfully tagged custom-nginx:latest
This command builds a new image based on our Dockerfile and tags it as custom-nginx
. The .
at the end tells Docker to look for the Dockerfile in the current directory.
Now, let's inspect the layers of our custom image:
docker inspect --format='{{.RootFS.Layers}}' custom-nginx
You'll notice that this image has one more layer than the original Nginx image. This additional layer represents the changes made by our RUN
command.
Understanding layers is crucial because:
- Layers are cached, speeding up builds of similar images
- Layers are shared between images, saving disk space
- When pushing or pulling images, only changed layers need to be transferred