Copyright (c) 2026 MindMesh Academy. All rights reserved. This content is proprietary and may not be reproduced or distributed without permission.

3.6.1. Container Runtimes and Image Operations

💡 First Principle: Container images are built in layers — each instruction in a Dockerfile creates a new immutable layer on top of the previous one. Layers are shared across images and cached during builds. A 500 MB base image shared by 10 containers occupies only 500 MB on disk, not 5 GB, because all 10 containers reference the same base layer.

Container Runtimes:
RuntimeDescriptionCLI
DockerMost popular; uses dockerd daemon (root)docker
PodmanDaemonless, rootless by defaultpodman (Docker-compatible)
containerdLow-level runtime; used by Kubernetesctr, nerdctl
runCOCI reference runtime; lowest levelrunc
Image Operations:
# Pull and manage images
docker pull nginx:1.25                     # Pull specific tag from Docker Hub
docker pull nginx:latest                   # Pull latest tag
docker images                              # List local images
docker image ls                            # Same as above
docker rmi nginx:1.25                      # Remove image
docker image prune                         # Remove unused images
docker image prune -a                      # Remove ALL unused images (including tagged)

# Build from Dockerfile
docker build -t myapp:1.0 .                # Build from ./Dockerfile, tag as myapp:1.0
docker build -t myapp:1.0 -f Dockerfile.prod .  # Use specific Dockerfile
docker tag myapp:1.0 registry.example.com/myapp:1.0  # Add registry tag
docker push registry.example.com/myapp:1.0           # Push to registry
Dockerfile Key Instructions:
# /project/Dockerfile
FROM ubuntu:22.04                    # Base image (always first)
FROM python:3.11-slim                # Minimal Python image

LABEL maintainer="alice@example.com"

RUN apt-get update && apt-get install -y nginx   # Run commands during build
RUN pip install -r requirements.txt              # Installs into image layer

COPY requirements.txt /app/           # Copy from build context to image
COPY . /app/                          # Copy all source files

WORKDIR /app                          # Set working directory

ENV LOG_LEVEL=info                    # Environment variable baked into image

EXPOSE 8080                           # Document which port the app uses

USER appuser                          # Run subsequent commands as this user (not root)

ENTRYPOINT ["python", "app.py"]       # Fixed command — cannot be overridden by docker run args
CMD ["--port", "8080"]                # Default args — can be overridden by docker run args
ENTRYPOINT vs CMD — the key distinction:
InstructionOverridablePurpose
ENTRYPOINTOnly with --entrypoint flagThe executable to run
CMDYes, by args after image nameDefault arguments to ENTRYPOINT
Both togetherCMD provides default argsFlexible: docker run myimage --port 9090 overrides CMD

⚠️ Exam Trap: USER in a Dockerfile does not create the user — it only switches to an existing user. If the user doesn't exist in the image, the image still builds; the failure surfaces at the next RUN step or when the container starts ("unable to find user"). You must create the user with RUN useradd -r appuser before the USER appuser instruction.

Reflection Question: A Dockerfile has ENTRYPOINT ["python", "app.py"] and CMD ["--port", "8080"]. What command does the container execute when started with docker run myimage --port 9090?

Alvin Varughese
Written byAlvin Varughese
Founder18 professional certifications