Image Build and Delivery

Building an image is only the first step. That image needs to travel from a developer’s machine to a registry, and from the registry to wherever containers run. Each step in that journey is a place where the wrong thing can get in or the right controls can be applied.
What a registry is
A registry is a server that stores and serves container images. Docker Hub is the public default. Organizations typically run a private registry (AWS ECR, Google Artifact Registry, GitHub Container Registry, or a self-hosted one) so they control who can push and who can pull.
When you run docker push, the image goes up to the registry. When a server runs docker pull, it downloads from there. The registry is on the critical path for every deployment.
flowchart LR
DF["Dockerfile"] -->|"docker build"| IMG["Local Image"]
IMG -->|"docker push"| REG[("Registry")]
REG -->|"docker pull"| SRV["Server / CI"]
SRV --> RUN["Running Container"]
Tags and digests
An image tag is a human-readable label like myapp:1.4 or myapp:latest. Tags are mutable: you can point latest at a different image tomorrow. A digest is a SHA-256 hash of the exact image content. It never changes. Pinning a digest in a deployment means you always get exactly what was tested, even if the tag moves.
Why image size matters for security
Every package in an image is something that can have a CVE. A 1 GB image built on a full OS base carries hundreds of packages your application never uses. A slim image with only the runtime and your code has fewer packages, fewer CVEs, and a smaller surface to patch. The lab in this section builds the same application two ways and compares the result.
Multi-stage builds
A multi-stage build uses more than one FROM instruction in a single Dockerfile. The first stage can install compilers and build tools. The final stage copies only the compiled output. Build tools never appear in what you ship. This is the standard way to keep production images small without maintaining two separate Dockerfiles.