Post

Docker - Containerization Notes

Concise Docker notes: images, containers, Dockerfiles, commands, and best practices.

Docker - Containerization Notes

Introduction

Docker simplifies software deployment by packaging applications and their dependencies into self-contained containers. Containers solve the “it works on my machine” problem by ensuring consistency across all systems. Multiple containers can work together for different services (databases, environments, etc.), and applications can be easily deployed and shared with all required dependencies included.

Quick overview

  • Image: a read-only, layered filesystem (built from a Dockerfile).
  • Container: a runtime instance of an image (writable top layer).
  • Registry: stores and distributes images (Docker Hub, private registries).
  • Docker Engine: the daemon that manages images and containers (it uses containerd and an OCI runtime).

Architecture (visual)

Traditional stack:

1
2
3
4
5
6
7
8
+------------------------+
|        Apps            |
+------------------------+
|   Operating System     |
|      (Host OS)         |
+------------------------+
| Physical Server / VM   |
+------------------------+

Containerized stack:

1
2
3
4
5
6
7
8
9
10
11
12
13
+------------------------------------------------+
| Containers                                     |
| +--------+  +--------+   +--------+            |
| |App 1   |  |App 2   |   |App 3   |            |
| |bins/lib|  |bins/lib|   |bins/lib|            |
| +--------+  +--------+   +--------+            |
+------------------------------------------------+
| Docker Engine (container runtime)              |
+------------------------------------------------+
| Operating System (Host OS)                     |
+------------------------------------------------+
| Physical Server / VM                           |
+------------------------------------------------+

How containers work (technical)

  • Namespaces: isolate kernel resources (pid, net, mnt, ipc, uts, user).
  • cgroups: limit and account for resources (CPU, memory, I/O).
  • Union filesystems (overlayfs): implement layered images with a writable container layer.
  • Runtime stack: Docker Engine → containerd → runc (OCI runtime) launches container processes.

Images are built as layers (Dockerfile instructions produce new layers); the union FS composes layers into a single filesystem for a container.

Image & container lifecycle

  • Build: docker build (image layers, cache).
  • Distribution: docker push / docker pull to/from registries.
  • Run: docker run starts a container; docker stop gracefully stops it.
  • Inspect / Cleanup: docker inspect, docker logs, docker rm, docker rmi.

Core components

  • Dockerfile: build recipe for images.
  • Images: layered, immutable artifacts.
  • Docker Engine (daemon + API).
  • containerd and runc: low-level runtime components.
  • Registry: public or private image storage.

Common commands (quick reference)

  • docker build -t name:tag . - build image
  • docker run --rm -it name:tag - run interactive container
  • docker ps -a - list containers
  • docker images - list images
  • docker pull name:tag / docker push name:tag - exchange images with registry

Security & best practices

  • Run processes as non-root inside containers when possible.
  • Use minimal base images and scan images for vulnerabilities.
  • Drop unnecessary Linux capabilities; use seccomp and AppArmor/SELinux profiles.
  • Limit host mounts and avoid privileged containers; prefer read-only root filesystems.
  • Consider rootless containers or user namespaces for stronger isolation in multi-tenant hosts.

Containers vs virtual machines (concise)

  • Containers share the host kernel: faster startup, smaller footprint.
  • VMs include a full guest kernel: stronger isolation, heavier resource use.
  • Use containers for microservices, CI/CD, and scalable deployments; use VMs when kernel-level separation is required.

In short,Docker leverages kernel features (namespaces, cgroups, union filesystems) to provide reproducible, efficient application environments. Images, registries, and a standardized runtime stack make building, sharing, and running applications simpler and more consistent across development and production.

Linux commands

Brief: Basic Linux CLI skills make working with Docker easier. Below are concise references and runnable examples.

Quick reference

  • whoami - show current user
  • echo 'text' - print text
  • ls -la - list files (including hidden)
  • cd <dir> - change directory
  • pwd - print working directory
  • cat <file> - show file contents
  • ps aux - list processes
  • touch <file> - create an empty file
  • mkdir <dir> - create a directory
  • rm <file> / rm -r <dir> - remove file/directory
  • cp <src> <dst> - copy files
  • mv <src> <dst> - move/rename files
  • nano <file> / vim <file> - edit text files
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Filesystem
ls -la
pwd
mkdir project && cd project
echo 'Hello from Docker notes' > hello.txt
cat hello.txt

# Processes
ps aux | head -n 10

# Docker quick checks
docker version
docker ps -a
docker image ls

Notes: Commands run inside many Linux containers are the same as on the host. Use --rm with short-lived containers and -it for interactive shells (docker run --rm -it ubuntu bash).

Docker images

Summary: Docker images are read-only, layered templates (built from a Dockerfile) that define what a container will run. Images are stored in registries (Docker Hub or private registries) and are identified by name:tag or digest.

Key concepts

  • Image vs container: an image is a static artifact; a container is a running instance of an image.
  • Layers & caching: images are composed of layers; Docker reuses cached layers when building.
  • Tags and digests: use tags for human-readable versions (e.g., nginx:latest) and digests for immutable references.

Common commands

1
2
3
4
5
6
7
8
9
10
11
12
13
# Pull an image from a registry
docker pull nginx:latest

# List local images
docker image ls

# Remove an image
docker rmi nginx:latest

# Build and push
docker build -t myapp:1.0 .
docker tag myapp:1.0 username/myapp:1.0
docker push username/myapp:1.0

Best practices

  • Prefer minimal/base images (e.g., alpine, debian:slim) to reduce size and attack surface.
  • Use multi-stage builds for compile-time dependencies.
  • Pull images only from trusted publishers or scan images for vulnerabilities.

Notes: Image sizes vary (e.g., lightweight images vs full OS images). Browse official and verified images at hub.docker.com when choosing a base image.

Containers

Summary: A container is a running instance of an image. Containers are lightweight, isolated processes that can be created, started, stopped, inspected, and removed.

Key concepts

  • Ephemeral instances: containers are usually short-lived but can run continuously (daemons).
  • Naming & IDs: each container has a unique ID and optional --name.
  • Modes: interactive (-it) vs detached (-d).
  • Networking: map host ports to container ports with -p host:container.
  • Storage: persist data using volumes (-v host_path:container_path).

Common commands

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Run a short container (prints then exits)
docker run --rm hello-world

# Run nginx detached and map to host port 8080
docker run -d --name web -p 8080:80 nginx:latest

# Run an interactive shell inside Debian
docker run --rm -it debian:stable bash

# List containers (running)
docker ps

# List all containers (including exited)
docker ps -a

# View logs, stop, remove
docker logs web
docker stop web
docker rm web

# Execute a command inside a running container
docker exec -it web bash

Notes: Use --rm for temporary containers, -d to run services in background, and --name to simplify management. Inspect containers with docker inspect <id|name>.

Dockerfiles

Summary: A Dockerfile is a text recipe that defines how to build an image. Each instruction creates a new layer; Docker caches layers to speed up rebuilds.

Common instructions

  • FROM <image> - base image
  • WORKDIR /path - set working directory
  • COPY <src> <dst> / ADD - copy files into the image
  • RUN <cmd> - run a command while building (creates a new layer)
  • ENV KEY=VALUE - set environment variables
  • EXPOSE <port> - document a port that the container listens on
  • CMD [...] / ENTRYPOINT [...] - default run command
  • VOLUME - declare mount points for persistent data

Example Dockerfile (Python app)

1
2
3
4
5
6
7
8
9
10
# Use a small Python base image
FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

EXPOSE 5000
CMD ["python", "app.py"]

Build and run:

1
2
docker build -t myapp:1.0 .
docker run -d -p 5000:5000 --name myapp myapp:1.0

Tips: use multi-stage builds to keep images small (FROM ... AS builder), minimize RUN layers, and avoid including secrets in the image. Use .dockerignore to exclude build-time files.

webservers

Summary: Web servers are commonly deployed in containers using official images (e.g., nginx, httpd). Key concerns are port mapping, persistent content, and running the process in the foreground inside the container.

Quick examples

1
2
3
4
5
6
7
8
9
10
11
12
# Run nginx (host port 8080 -> container port 80)
docker run -d --name nginx -p 8080:80 nginx:stable

# Serve a local site directory (read-only volume)
docker run -d --name site -p 8080:80 -v $(pwd)/site:/usr/share/nginx/html:ro nginx:stable

# Run Apache (httpd) on port 8080
docker run -d --name apache -p 8080:80 httpd:latest

# Stop and remove
docker stop nginx
docker rm nginx

Dockerfile for a static site (nginx)

1
2
3
4
FROM nginx:stable
COPY ./site /usr/share/nginx/html:ro
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Notes: Expose ports with -p, persist user content with volumes (-v), and keep the server process running in foreground (many images already do this). Use healthchecks and non-root users for production deployments.

Final Certification

This post is licensed under CC BY 4.0 by the author.