Understanding Docker Images: Layers, Base Images & Docker Hub

Docker layered architecture

In Episode 2, we ran containers using images like nginx and hello-world without really thinking about what those images actually are. We just typed a command and things worked. That’s the magic of Docker, but now it’s time to look under the hood.

In this episode, we’ll answer: What exactly is a Docker image? How is it built? And how do you find the right one for your project?

Understanding images is the foundation for everything that comes next — especially writing your own Dockerfile in Episode 4.

What Is a Docker Image?

A Docker image is a read-only template that contains everything needed to run an application: the code, runtime, libraries, environment variables, and configuration files.

Think of an image as a recipe and a container as the meal you cook from it. The recipe doesn’t change , but you can cook as many meals from it as you want. Similarly, one image can be used to launch dozens of identical containers simultaneously.

Key points to remember:

  • Images are read-only — they never change once built
  • Containers are running instances of an image
  • You can run multiple containers from the same image
  • Images are stored locally on your machine and can be shared via registries like Docker Hub

How Docker Images Are Built in Layers

This is where things get clever. Docker images are not single giant files — they are built from a stack of layers, where each layer represents a change or addition.

Imagine building a cake:

  • Layer 1 — the base sponge (operating system)
  • Layer 2 — the filling (runtime, e.g. Node.js or Python)
  • Layer 3 — the icing (your application code)
  • Layer 4 — decorations (configuration and environment variables)

Each layer only contains the difference from the layer below it. This is called a union file system.

Why layers matter

Efficiency: If two images share the same base layer (say, both use Ubuntu), Docker only stores that layer once on your machine — saving significant disk space.

Speed: When you rebuild an image after changing your code, Docker only rebuilds the layers that changed. The unchanged layers are pulled from cache instantly. This makes builds dramatically faster.

Shareability: When you push an image to Docker Hub, only the layers that aren’t already on the server get uploaded. Same when pulling — you only download what you don’t already have.

You can inspect an image’s layers with:

docker image inspect nginx

Or see a visual history of how it was built:

docker history nginx

This shows each layer, how it was created, and how much space it takes up. (Make sure to run the Docker Desktop application before running these commands)

What Are Base Images?

Every Docker image starts from a base image — the foundation layer that everything else is built on top of.

Base images come in a few flavors:

1. OS base images

These are minimal operating system images. The most commonly used ones are:

  • ubuntu — familiar Linux environment, great for general use
  • debian — similar to Ubuntu, slightly leaner
  • alpine — an extremely minimal Linux distro, only ~5MB. Very popular for keeping image sizes small.
  • scratch — literally empty. Used for building ultra-minimal images from nothing.

2. Language runtime images

These start with an OS and add a language runtime on top:

  • node:20 — Node.js 20 on Debian
  • python:3.12 — Python 3.12
  • openjdk:21 — Java 21
  • golang:1.22 — Go 1.22
  • php:8.3 — PHP 8.3

3. Application images

These come with a full application already configured:

  • nginx — Nginx web server, ready to serve files
  • postgres — PostgreSQL database
  • redis — Redis in-memory data store
  • wordpress — WordPress CMS with PHP included

When you write your own Dockerfile (Episode 4), the very first line will always be FROM <base-image> , declaring which foundation to build on.

Official Images vs. Community Images

On Docker Hub, images fall into two main categories:

Official Images

These are maintained by Docker Inc. or the software’s core team. They are regularly updated, security-patched, and follow best practices. They have clean, simple names with no username prefix:

nginx
postgres
python
node
redis

Always prefer official images for production use or learning. They’re reliable and well-documented.

Community / User Images

These are published by individual developers or organizations. They follow the format username/imagename:

bitnami/wordpress
grafana/grafana
linuxserver/plex

Community images can be excellent; many are maintained by reputable organizations, but always check the number of pulls, stars, and when it was last updated before trusting one.

Docker Hub: Your Image Registry

Docker Hub (hub.docker.com) is the default public registry where Docker pulls images from. Think of it as the App Store for containers.

Searching for images

You can search directly from the terminal:

docker search python

This returns a list of images matching “python” with their description, star count, and whether they’re official. But for a better experience, search at hub.docker.com where you can filter by category and read full documentation.

Understanding image tags

Every image has a tag that identifies a specific version. The format is:

imagename:tag

Examples:

docker pull node:20          # Node.js version 20
docker pull node:20-alpine   # Node.js 20 on Alpine (smaller)
docker pull node:latest      # The most recent stable version
docker pull node             # Same as :latest

Important: Using :latest is convenient but risky in production — the image can change without warning and break your app. Always pin to a specific version tag in real projects, like node:20.11.0.

Common tag suffixes you’ll see

Tag suffixWhat it means
:latestMost recent stable release
:alpineBuilt on Alpine Linux — much smaller size
:slimA trimmed-down version of the standard image
:bookwormBased on Debian Bookworm (current stable)
:ltsLong-term support version
:<version>A specific pinned version number

Pulling and Managing Images Locally

Pull an image without running it

docker pull python:3.12-slim

This downloads the image to your machine so it’s ready to use instantly when you need it.

List images on your machine

docker images

Output looks like:

REPOSITORY   TAG          IMAGE ID       CREATED        SIZE
nginx        latest       a72860cb95fd   2 weeks ago    188MB
python       3.12-slim    8b0a1f1e2f3c   3 weeks ago    130MB
node         20-alpine    c4f9f5e3b2a1   1 month ago    135MB
hello-world  latest       d2c94e258dcb   1 year ago     13.3kB

Remove an image you no longer need

docker rmi python:3.12-slim

Note: you can’t remove an image if a container (even a stopped one) is still using it. Remove the container first with docker rm.

Clean up everything unused at once

docker system prune

This removes all stopped containers, unused networks, and dangling images in one shot. Add -a to also remove images not tied to any container:

docker system prune -a

Image Size Matters

One thing beginners often overlook is image size. Large images mean:

  • Slower pull times when deploying
  • More storage used on servers
  • Larger attack surface for security vulnerabilities

A few practical tips to keep images lean:

Use Alpine variants when you can. The difference is dramatic:

ImageSize
node:20~1.1 GB
node:20-slim~240 MB
node:20-alpine~135 MB

Don’t pull images you don’t need. Only use the base image that matches what your app actually requires.

Remove build tools after using them. When writing Dockerfiles (next episode), install build dependencies and then delete them in the same layer.

Putting It All Together: The Image Lifecycle

Here’s the full lifecycle of a Docker image, from creation to running a container:

  1. Someone writes a Dockerfile — a set of instructions for building the image
  2. docker build — the Dockerfile is executed layer by layer, creating the image
  3. docker push — the image is uploaded to Docker Hub or a private registry
  4. docker pull — someone else downloads the image to their machine
  5. docker run — A container is created from the image and starts running
  6. docker stop / docker rm — the container is stopped and cleaned up
  7. The image itself remains unchanged and ready to spawn more containers

Quick Reference: Image Commands

CommandWhat it does
docker pull <image>:<tag>Download an image from Docker Hub
docker imagesList all locally stored images
docker image inspect <image>Show detailed metadata about an image
docker history <image>Show the layer history of an image
docker rmi <image>Delete a local image
docker search <term>Search Docker Hub from the terminal
docker system prune -aRemove all unused images and containers
docker tag <image> <new-name>Give an image a new name or tag

What’s Next?

You now understand what Docker images are, how their layer system works, and how to find and manage them. This sets you up perfectly for the most hands-on episode yet.

In Episode 4, we’ll write our very first Dockerfile — building a custom image for a real application from scratch. You’ll see exactly how each instruction in a Dockerfile creates a new layer, and by the end you’ll have your own image ready to run anywhere.

Leave a Reply

Your email address will not be published. Required fields are marked *