Building and Tagging Images

intermediate
10 min

Building and Tagging Images

Writing a Dockerfile is half the story - turning it into well-named, versioned images that your team and servers can pull is the other half. This lesson covers the build command in depth, tagging conventions, and publishing images to a registry.

Anatomy of docker build

bash
docker build -t myapp:1.0 .
  • -t myapp:1.0 assigns a name and tag in one step.
  • The final . is the build context: Docker packages this directory and sends it to the daemon, and only files inside it can be COPYed.

Useful variations:

bash
docker build -f docker/Dockerfile.prod -t myapp:1.0 . # custom Dockerfile path docker build --no-cache -t myapp:1.0 . # ignore layer cache docker build --build-arg VERSION=2.5 -t myapp:2.5 . # pass ARG values

--no-cache forces every step to re-run - handy when a RUN step fetches remote resources that may have changed.

Understanding Image Names

A full image reference has up to four parts:

registry.example.com/team/myapp:1.4.2 └── registry ──┘ └─ repo ─┘ └ tag ┘
  • Registry: where the image lives. Omitted means Docker Hub.
  • Repository: the image name, often username/project on Docker Hub.
  • Tag: a label for a specific build. Omitted means latest.

Important: latest is not magic. It is just the default tag name - it does not automatically point to the newest version. If you push myapp:2.0 without also pushing myapp:latest, the latest tag still refers to whatever it referred to before.

Tagging Strategies

One physical image can carry several tags - tags are just pointers to an image ID. A common release flow tags the same build three ways:

bash
docker build -t myapp:1.4.2 . docker tag myapp:1.4.2 myapp:1.4 docker tag myapp:1.4.2 myapp:latest

Consumers can then choose their stability level: pin to 1.4.2 for exact reproducibility, track 1.4 for patch updates, or ride latest in development. Many teams also tag images with the git commit hash for perfect traceability:

bash
docker build -t myapp:$(git rev-parse --short HEAD) .

Pushing to a Registry

To share an image, push it to a registry. With Docker Hub:

bash
docker login docker tag myapp:1.4.2 yourname/myapp:1.4.2 docker push yourname/myapp:1.4.2

The repository name must include your Docker Hub username. For private registries such as GitHub Container Registry or AWS ECR, prefix with the registry host:

bash
docker tag myapp:1.4.2 ghcr.io/yourname/myapp:1.4.2 docker push ghcr.io/yourname/myapp:1.4.2

Anyone with access can now run docker pull followed by the same reference.

Watching the Cache Work

Run the same build twice and read the output. Steps whose inputs are unchanged print CACHED and complete instantly. Change one line of source code and rebuild: every step after the COPY of that code re-runs, while earlier steps stay cached. Structuring Dockerfiles so the expensive steps come before frequently-changing files is the key to fast builds.

You can inspect what ended up in each layer with:

bash
docker history myapp:1.4.2

Cleaning Up Build Artifacts

Repeated builds leave behind dangling images - old layers with no tag, shown as <none> in docker images. Reclaim the space with:

bash
docker image prune

Key Takeaways

  • docker build -t name:tag . builds from a Dockerfile using the given directory as context.
  • An image reference is registry/repository:tag; missing parts default to Docker Hub and latest.
  • latest is only a naming convention - always push explicit version tags for production.
  • Tags are cheap pointers: tag one build with version, minor version, and commit hash.
  • docker push publishes images; docker image prune clears dangling layers.

Next up: Volumes and Persistent Data, where you will learn how containers store data that survives restarts and removals.

Building and Tagging Images - Docker | CodeYourCraft | CodeYourCraft