3. Docker Images: Layers, Tags, and Management | The Complete Docker Handbook.
Welcome to Article 3 of The Complete Docker Handbook.
In Article 2, you installed Docker and ran your first containers using pre-built images like ubuntu and hello-world. You treated these images like magic boxes—you pulled them, ran them, and deleted them.
But what is actually inside an image? How does Docker store them so efficiently? And why do we see tags like :latest or :alpine?
In this article, we are going to pop the hood. We will explore the layered architecture of Docker images, understand how caching works, and learn how to manage your image library like a pro. This knowledge is crucial before we start building our own custom images in Article 4.
1. The Layered Architecture (The Onion Model)
The most important concept to understand about Docker images is that they are made of layers.
When you look at an image, it might seem like a single file. In reality, it is a stack of read-only layers. Each layer represents a specific instruction or change to the file system.
How Layers Work
Imagine you are building a sandwich:
- Base Layer: A slice of bread (The Operating System, e.g., Ubuntu).
- Layer 2: Add cheese (Install Python).
- Layer 3: Add ham (Install Dependencies).
- Top Layer: Add lettuce (Your Application Code).
In Docker, each of these steps is a layer.
Why Layers Matter
- Reusability: If you have two images that both use Ubuntu as a base, Docker only stores the Ubuntu layer once on your disk. Both images share it. This saves massive amounts of space.
- Caching: When building images (which we will do in Article 4), Docker caches layers. If you change only the top layer (your code), Docker doesn't need to rebuild the bottom layers (the OS). This makes builds incredibly fast.
- Copy-on-Write: When you run a container, Docker adds a thin writable layer on top of the image layers. Any changes you make (creating files, installing apps) happen here. When the container is deleted, this writable layer is deleted. The underlying image remains unchanged.
[Visual Idea: Diagram showing stacked layers (Base OS -> Tools -> App) vs. a single monolithic block]
2. Image Tags and Versioning
When you ran docker run ubuntu, you actually ran docker run ubuntu:latest. The :latest part is the tag.
Tags are labels attached to specific image IDs. They help you manage versions.
Common Tagging Strategies
:latest: Points to the most recent build.- Warning:
latestchanges over time. If you build your app today usingpython:latest, and someone else builds it next month, they might get a different version of Python, causing bugs. Avoid using:latestin production.
- Warning:
:version(e.g.,:3.9,:18.04): Points to a specific version.- Best Practice: Always pin specific versions for reproducibility.
:alpine: Indicates a lightweight version of the image based on Alpine Linux (often only 5MB vs 100MB+).- Trade-off: Smaller size, but some standard libraries might be missing.
Example: Pulling Specific Versions
Bash1# Pulls the newest version (risky for prod)
2docker pull python:latest
3
4# Pulls a specific version (safe for prod)
5docker pull python:3.9.7
6
7# Pulls a lightweight version
8docker pull python:3.9.7-alpine
3. Inspecting Images
Sometimes you need to know what's inside an image before you run it. Docker provides tools to peek inside.
Check Image History
The docker history command shows the layers that make up an image.
Bashdocker history ubuntu
Output:
Plain Text1IMAGE CREATED CREATED BY SIZE COMMENT 2f04fe58... 2 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B 3d70eaf7... 2 weeks ago /bin/sh -c #(nop) ADD file:... 72.8MB 4 2 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers... 0B
- CREATED BY: Shows the command that created that layer.
- SIZE: Shows how much space each layer adds. This is vital for optimization (we will cover this in Article 5).
Deep Inspection
For detailed metadata (environment variables, entry points, configuration), use inspect.
Bashdocker inspect ubuntu
This returns a large JSON object. You can use grep or flags to find specific info:
Bash1# Find the IP address (if running) or specific config
2docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
4. Managing Your Image Library
As you experiment, your disk will fill up with unused images. Here is how to keep your system clean.
List Images
Bashdocker images
- REPOSITORY: The name of the image.
- TAG: The version label.
- IMAGE ID: The unique hash identifier.
- SIZE: Disk space used.
- CREATED: How long ago it was built.
Remove Images
To delete an image, use the rmi (remove image) command.
Bashdocker rmi
- Error Handling: If you get an error saying the image is being used by a container, you must remove the container first (see Article 2) or use the force flag
-f.Plain Text1bash 2docker rmi -f
Pruning Unused Images
To clean up all images that are not used by any container (dangling images):
Bashdocker image prune
To remove all unused images (not just dangling ones):
Bashdocker image prune -a
> ⚠️ Warning: prune -a will delete any image not currently attached to a running or stopped container. Use with caution!
5. Docker Registries
Where do images live? In a Registry.
- Docker Hub: The default public registry (like GitHub for images). When you type
docker pull ubuntu, Docker searches Docker Hub. - Private Registries: Companies often host their own private registries (using tools like Harbor, AWS ECR, or Google GCR) to store proprietary code securely.
Logging into a Registry
To pull private images or push your own, you need to log in:
Bashdocker login
Enter your Docker Hub username and password (or access token).
Searching for Images
You can search Docker Hub from the terminal:
Bashdocker search nginx
Look for the *OFFICIAL* column. Official images are maintained by the Docker team or the software vendor and are generally more secure.
6. Summary of Image Commands
| Command | Description |
|---|---|
docker images | List all local images |
docker pull | Download an image from a registry |
docker rmi | Delete an image |
docker history | Show the layers of an image |
docker inspect | View detailed JSON metadata |
docker image prune | Clean up unused images |
What's Next?
You now understand the anatomy of an image. You know about layers, tags, and how to manage storage. But so far, you've only used images created by other people.
The real power begins when you create the blueprint.
In Article 4, we will write your first Dockerfile. You will learn:
- The syntax (
FROM,RUN,COPY,CMD). - How to containerize a simple web application.
- The difference between
CMDandENTRYPOINT.
Link: Read Article 4: Writing Your First Dockerfile
Summary Checklist
By the end of this article, you should understand:
- How Docker image layers work (Union File System).
- Why you should avoid the
:latesttag in production. - How to inspect image layers with
docker history. - How to clean up unused images with
prune. - The role of Docker Hub and Registries.
Question of the Day: Have you ever run into a "disk full" error due to Docker? Let us know in the comments how you cleaned it up!
Next Up: Writing Your First Dockerfile