Building & Pushing Images

3 minute read

Building Container Images

Building an image takes a Dockerfile and a build context (all files in the specified directory) and produces a tagged image that you can run or push.

Basic Build Commands

# Build from current directory (uses ./Dockerfile)
docker build -t my-app:v1 .

# Build with a specific Dockerfile
docker build -t my-app:v1 -f Dockerfile.prod .

# Build with build arguments
docker build -t my-app:v1 --build-arg VERSION=2.0 .

# Build with no cache (force rebuild all layers)
docker build -t my-app:v1 --no-cache .

Build Command Breakdown

Flag Purpose Example
-t Tag the image (name:version) -t my-app:v1
-f Specify Dockerfile path -f Dockerfile.prod
--build-arg Pass build-time variables --build-arg ENV=prod
--no-cache Rebuild without layer cache --no-cache
--target Build up to a specific stage --target builder
. Build context directory . (current dir)

What Happens During a Build

docker build -t my-app:v1 .
           │                 │
           │                 └── Build context (files sent to Docker)
           └── Tag for the resulting image

Step 1/6 : FROM python:3.12-slim     ← Pull (or use cached) base
Step 2/6 : WORKDIR /app              ← Set working directory
Step 3/6 : COPY requirements.txt .   ← Copy file from context
Step 4/6 : RUN pip install ...       ← Execute command (new layer)
Step 5/6 : COPY . .                  ← Copy remaining files
Step 6/6 : CMD ["python", "app.py"]  ← Set default command

Successfully built 4a2b3c1d5e6f
Successfully tagged my-app:v1

Build Context and .dockerignore

The build context is everything in the directory you specify (.). Large contexts slow down builds. Use .dockerignore to exclude unnecessary files:

# .dockerignore
node_modules
.git
.env
*.md
Dockerfile
docker-compose.yml
__pycache__
.pytest_cache

Tip: Always check your build context size. If you see “Sending build context to Docker daemon 500MB”, you need a .dockerignore file.

Tagging Images

Tags identify specific versions of an image. Proper tagging is essential for reliable deployments.

Tagging Conventions

# Tag during build
docker build -t my-app:v1.0.0 .

# Add additional tags to an existing image
docker tag my-app:v1.0.0 my-app:latest
docker tag my-app:v1.0.0 registry.example.com/team/my-app:v1.0.0

# Tag with Git commit SHA (common in CI/CD)
docker tag my-app:v1.0.0 my-app:sha-$(git rev-parse --short HEAD)

Common Tagging Strategies

Strategy Example Use Case
Semantic versioning v1.2.3 Production releases
Git commit SHA sha-abc123 CI/CD pipelines
Branch name main, develop Development builds
Date-based 2025-02-09 Nightly builds
latest latest Most recent build (use cautiously)

Warning: Avoid relying on latest in production. It’s mutable — different nodes might pull different versions. Always use specific tags.

Pushing Images to a Registry

After building, push your image to a container registry so Kubernetes can pull it.

Push Workflow

Build locally → Tag for registry → Login → Push
# 1. Build the image
docker build -t my-app:v1 .

# 2. Tag for the remote registry
docker tag my-app:v1 registry.example.com/team/my-app:v1

# 3. Login to the registry
docker login registry.example.com

# 4. Push to the registry
docker push registry.example.com/team/my-app:v1

Common Registry Providers

Registry Domain Example
Docker Hub docker.io docker.io/myuser/app:v1
GitHub Container Registry ghcr.io ghcr.io/org/app:v1
Google Container Registry gcr.io gcr.io/project/app:v1
Amazon ECR <id>.dkr.ecr.<region>.amazonaws.com 123456.dkr.ecr.us-east-1.amazonaws.com/app:v1
Azure Container Registry <name>.azurecr.io myregistry.azurecr.io/app:v1

Pushing to Docker Hub

# Login
docker login

# Tag with your Docker Hub username
docker tag my-app:v1 myusername/my-app:v1

# Push
docker push myusername/my-app:v1

Pushing to GitHub Container Registry (GHCR)

# Login with personal access token
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin

# Tag
docker tag my-app:v1 ghcr.io/myorg/my-app:v1

# Push
docker push ghcr.io/myorg/my-app:v1

Using Podman (Alternative to Docker)

Podman is a daemonless container engine that uses the same CLI syntax as Docker. Some CKAD environments or organizations use Podman instead of Docker.

# Build an image (same syntax)
podman build -t my-app:v1 .

# Run a container
podman run -d -p 8080:80 my-app:v1

# Push to a registry
podman push my-app:v1 registry.example.com/team/my-app:v1

# List images
podman images

Docker vs Podman Comparison

Feature Docker Podman
Daemon Requires dockerd Daemonless
Root required By default (rootless mode available) Rootless by default
CLI syntax docker ... podman ... (compatible)
Compose docker compose podman-compose
Kubernetes YAML ❌ podman generate kube

CKAD relevance: The exam may use either Docker or Podman. The CLI commands are interchangeable — podman build, podman push, etc. work the same way.

Listing and Inspecting Images

# List all local images
docker images

# Inspect image details (layers, config, size)
docker inspect my-app:v1

# View image history (layers)
docker history my-app:v1

# Remove an image
docker rmi my-app:v1

# Remove unused images
docker image prune

Summary

Task Command
Build image docker build -t name:tag .
Tag image docker tag source:tag target:tag
Login to registry docker login registry.example.com
Push image docker push registry/name:tag
List images docker images
Inspect image docker inspect name:tag

Updated: