Containerised Systems (Docker Hub Images)

Docker popularised container technology for packaging, distributing, and running applications. A container is a standardised unit of software that packages code and all its dependencies, enabling applications to run quickly and reliably from one computing environment to another.

Images and Containers

  • Image: A read-only template containing an application and its dependencies. Built from a Dockerfile.
  • Container: A running instance of an image, with a writable layer on top.

Images are stored in registries, with Docker Hub being the default public registry.

Basic Commands

docker pull nginx:latest       # Download an image
docker run -d -p 80:80 nginx  # Run a container
docker ps                     # List running containers
docker stop nginx             # Stop a container
docker rm nginx               # Remove a stopped container
docker images                 # List local images
docker rmi nginx              # Remove an image

Dockerfiles

A Dockerfile defines how to build an image:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

Build and tag:

docker build -t myapp:1.0 .

Multi-Stage Builds

Multi-stage builds reduce image size by separating build and runtime environments:

# Build stage
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o server .

# Runtime stage
FROM alpine:3.19
COPY --from=builder /app/server /usr/local/bin/
CMD ["server"]

Volumes and Data Persistence

Containers are ephemeral. Use volumes for persistent data:

docker volume create mydata
docker run -v mydata:/data myapp

Bind mounts map host directories:

docker run -v /host/path:/container/path myapp

Networks

Docker provides a virtual network for containers:

docker network create mynet
docker run --network mynet --name db postgres
docker run --network mynet --name app myapp

Docker Compose

Docker Compose defines multi-container applications in YAML:

# docker-compose.yml
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
docker compose up -d          # Start services
docker compose down           # Stop services
docker compose logs web       # View logs

Registries

Images are distributed through registries:

  • Docker Hub: Default public registry.
  • GitHub Container Registry (GHCR): Integrated with GitHub.
  • Quay.io: Red Hat's registry, popular for Kubernetes.
  • Private registries: Self-hosted or cloud provider registries (AWS ECR, GCR, ACR).

Security Considerations

  • Run containers as non-root users.
  • Use minimal base images (distroless, scratch).
  • Scan images for vulnerabilities (docker scout, trivy).
  • Pin image versions in production (avoid latest).
  • Limit container capabilities (--cap-drop ALL).