Working with Images: pull, tags, layers and cleanup
Pull images from Docker Hub, understand tags, digests and layers, compare image sizes, tag your own copies and reclaim disk space.
On this page 12 sections
Introduction
Every container starts from an image, so choosing and managing images well matters: it affects how fast your containers download, how much disk they use and how secure they are. This lesson covers where images come from and how to work with them.
- What Docker Hub and official images are.
- How image names, tags and digests work.
- Why the same software comes in images of very different sizes.
- How images are built from layers, and how to tag, remove and clean up images.
Docker Hub and Official Images
Docker Hub (hub.docker.com) is the default registry: when you name an image without a registry, Docker looks there. Anyone can publish images to it, so prefer trusted sources:
| Kind | Example name | Who publishes it |
|---|---|---|
| Docker Official Images | nginx, python, postgres, alpine | Curated and regularly updated in partnership with Docker |
| Verified publishers | grafana/grafana, bitnami/redis | Companies verified by Docker |
| Community images | priya/quotes-api | Any user — check before trusting |
The full name of an image is registry/namespace/repository:tag. Official images live in the library namespace, so nginx:alpine is short for docker.io/library/nginx:alpine — which is exactly what the pull output prints.
Pulling Images and Tags
docker run pulls images automatically, but docker pull downloads one without running it — useful to prepare a machine in advance:
docker pull nginx:alpineClick Run to see what this code prints.
A tag names a version or variant of an image. Popular images publish many tags — for example nginx:1.31, nginx:alpine or python:3.14-slim. If you leave the tag out, Docker uses latest, which simply means whatever the publisher last labelled that way — not necessarily the newest version, and it changes over time. Pulling again only downloads something if the tag now points to a different image:
docker pull nginx:alpineClick Run to see what this code prints.
The digest (sha256:...) identifies the exact image content and never changes. Tags can be moved to newer images; a digest cannot. When you need to be certain you are running exactly the same image, you can pull by digest: docker pull nginx@sha256:....
Listing Images
docker imagesClick Run to see what this code prints.
| Column | Meaning |
|---|---|
| IMAGE | The name and tag |
| ID | The start of the image’s unique ID (the same as its digest here) |
| DISK USAGE | Space the image uses on your disk, unpacked |
| CONTENT SIZE | The compressed size — roughly how much is downloaded |
| EXTRA | Flags such as U when a container is using the image |
(The first line is a small legend that Docker 29 prints above the table when you use a terminal. docker image ls is the same command.)
Image Variants and Size
Most official images come in several variants. Priya compares two Python 3.14 images — slim (based on a trimmed-down Debian) and alpine (based on the tiny Alpine Linux). -q makes pull print only the image name:
docker pull -q python:3.14-slimdocker pull -q python:3.14-alpinedocker images pythonClick Run to see what this code prints.
| Variant | Based on | Good for |
|---|---|---|
| python:3.14 (no suffix) | Full Debian with many build tools | When you need to compile packages and do not care about size |
| python:3.14-slim | Minimal Debian | A safe default for most apps: small, and compatible with almost all packages |
| python:3.14-alpine | Alpine Linux (musl instead of glibc) | The smallest images, but some packages need extra work to install |
Smaller images download and start faster, cost less to store, and contain fewer programs that could have security vulnerabilities. This course uses slim images for Python apps and alpine images for tools such as Nginx, Redis and PostgreSQL.
Layers: docker history
An image is a stack of read-only layers. Each instruction in its Dockerfile adds a layer, and layers are shared: two images based on the same Alpine version store that base layer only once. That is why, in lesson 3, pulling nginx:alpine after alpine reported one layer as “Already exists” — the Alpine base layer was already on disk. docker history lists an image’s layers, newest first:
docker history nginx:alpineClick Run to see what this code prints.
Read from the bottom up: Alpine’s root filesystem (ADD alpine-minirootfs…), then Nginx being installed, configuration scripts copied in, the port it uses (EXPOSE) and the command it runs (CMD). Lines with size 0B only change settings. docker image inspect shows those settings directly:
docker image inspect nginx:alpine --format "Cmd: {{.Config.Cmd}} Ports: {{.Config.ExposedPorts}}"Click Run to see what this code prints.
Tagging and Removing Images
docker tag gives an image an extra name. It does not copy anything — both names point to the same image ID:
docker tag nginx:alpine my-nginx:1.0docker imagesClick Run to see what this code prints.
docker rmi removes a name. Because nginx:alpine still points to the same image, only the tag is removed:
docker rmi my-nginx:1.0Click Run to see what this code prints.
Docker will not remove an image that a container is using, even a stopped one. Here Priya starts a container from python:3.14-alpine, then tries to remove the image:
docker run -d --name py python:3.14-alpine sleep 600docker rmi python:3.14-alpineClick Run to see what this code prints.
Priya runs docker tag nginx:alpine my-nginx:1.0. How much extra disk space does this use?
Cleaning Up
Images take up a lot of space over time. After removing the container that was using it, Priya cleans up. docker image prune removes unused “dangling” images (left behind by rebuilds); with -a it removes every image not used by any container:
docker rm -f pydocker image prune -a -fClick Run to see what this code prints.
Over 300 MB reclaimed. Nothing is lost permanently — any image can be pulled again when it is needed. For a full clean-up of stopped containers, unused networks, unused images and the build cache, there is docker system prune (add -a for all unused images); docker system df shows how much space each kind of object uses.
Common Mistakes
- Relying on latest in production — it can change underneath you. Use a specific version tag.
- Running images from unknown publishers without checking them.
- Using full, non-slim base images by default and ending up with gigabyte-sized images.
- Never cleaning up, then running out of disk space — check docker system df occasionally.
Frequently Asked Questions
Yes. Docker Hub limits how many images can be pulled per hour, with higher limits for users who are logged in (docker login) and for paid plans. Normal learning use stays well within the limits.
They are managed by the Docker daemon — on Linux under /var/lib/docker, and on Windows and macOS inside Docker Desktop’s virtual machine. Always manage them with docker commands rather than touching those files.
Those layers were built on another machine (the publisher’s), so their intermediate IDs are not available locally. It is normal for any pulled image.
Key Takeaways
- Images are named registry/namespace/repository:tag; Docker Hub is the default registry.
- Prefer official images and specific version tags; latest is just a moving label.
- Digests identify exact image content; tags can move.
- slim and alpine variants are far smaller than full images.
- Images are stacks of shared layers; docker tag adds names, rmi removes them, prune reclaims space.
Summary
You can now find, choose and manage images. In the next lesson you will build your own image for Priya’s Python API by writing a Dockerfile.