EDUCATION, DOCKER, CONTAINERS

🐳 Docker and containerisation

In simple language, with a security view - from the road map (why the containers were created and where they were carried) to the teams, the environment and safety. Each topic has clear advantages and disadvantages. International practice (OCI, NIST SP 800-190, CIS Docker Benchmark). Examples are general, intended for training.

Where Docker fits and where it leads

Road map: from server to container infrastructure

Road map from physical servers to container orchestrating Six steps in the development of placement - physical servers, virtual machines, container, image and register, Docker Compose and orchestrating - with increasing safety importance towards the product. From server to container infrastructure Grey - before Docker, colorful - themes of this guide 1 Physical servers one application 2 Virtual machines multiple OS 3 Container common core 4 Image + Register packaging, shared 5 Compose many containers 6 Orchesting scale, K8s Time, maturity, scale Security: the closer to production, the more critical insulation, reliable and scanned images, secrets outside the image, network segmentation This guide: container → image → commands → Compose → security

How to Read the Guide

The road map shows why the containers were born (VM were heavy) and where they were carried (austerage). Next tabs go step by step - from one container to multi-container environment and safety.

Reference

Development of placement: physical server → virtualization → containers → orchestrating (Cubernetes). OCI, NIST SP 800-190.

Security View

Each step adds security tasks: insulation (container), reliable images (registry), secrets and networks (Compose), policies and scanning (Orchestration).

Basics of containerization

Virtual machine vs container

Comparison of virtual machine and container On the left, virtual machines, each with its own full operating system; on the right, containers that divide one core of a host and are therefore lighter. Virtual machine vs container Containers divide the core of a host - therefore easier and faster Virtual machines Application A Application B Application C Guest OS Guest OS Guest OS Hypervisor Infrastructure Containers Application A Application B Application C Library Library Library Docker Engine Host OS - one common core Infrastructure its core for each VM = strong insulation, but heavy common core = light but weaker insulation Security: a common core → breakthrough (escape) can threaten the host

Containers are easy and fast because they divide the core of a host - but that is why isolation is weaker than virtual machines. This is the main safety compromise.

● Analogy without pre-existing knowledge

Imagine a house. Virtual machine it is as if each citizen would build a completely separate house - with its foundation, roof and water pipe. Safe (one home problem does not touch the neighbors), but expensive and slow to build. Container is like an apartment in an apartment house - each resident has its own premises with its own doors, but the foundation, roof and pipes are in common for the whole building. Cheaper and faster construction, but a thinner bulkhead means that a serious problem (e.g. a fire on the ground) can affect all citizens at once. Host (host) in this analogy is the building itself - the physical or virtual server on which Docker works.

Advantages (+)

  • Transferability - works equally in design, test and production
  • Fast start (seconds) and resource efficiency
  • Easy to scale, update and return version
  • Repeatable environment - "work on my computer" problem disappears
  • Applications isolated from each other

Deficiencies and risks (-)

  • Common core - weaker insulation than VM (break-out risk)
  • Data are temporary - without volume they disappear
  • Broader security surface - images with injuries (CVE)
  • Incorrect configuration (root, --privileged) = high risk
  • Scale - complexity of orchestrating and new skills

Security View

Insulation is provided by Linux core mechanisms (namespaces, groups, capabilities). Root in a container plus nuclear vulnerability = breakthrough on a host. Therefore, do not act like a root, and give up unnecessary privileges.

When containers fit

Containers are suitable for most applications - microservis, development environment, CI/CD, fast scalability. If you have to start a completely unreliable code (e.g. scripts uploaded by foreign users) - VM or additional insulation layer (gVisor, Kata Containers) is considered.

Reference

OCI (Open Container Initiative) - image and execution time standards, NIST SP 800-190, Linux namespaces / groups, Docker / containerd.

Two main concepts

Image = Template, Container = Launched instance

Image, register and container The image is downloaded from the register and is only a readable set of layers; docker run creates a container that is an image plus a writing layer. Image → Container Image = recipe (form), container = ready-to-eat (instance) Register Docker Hub, GHCR, private Image - Read-only layer 1: application code layer 1: libraries layer 1: executing medium layer 1: minimum base system Container - running a writing layer application code (to be read) libraries (readable) executable environment (readable) base OS (readable) docker pull docker run One image → many containers, the writing layer disappears when the container is removed

In practice

The image is a constant template that can be shared and versioned; many identical containers are released from one image. The environment is therefore repeatable and predictable.

Reference

OCI Image Specification, Docker Hub / GitHub Container Registry (GHCR), image layers (layers) and their cacheling.

Security View

An image from a unreliable source may contain a vulnerable or rear door. Uses official or signed images, scans them (CVE) and records versions. The writing layer is temporary - constant data requires volume.

Follow and try

Practical example: from one file to an operating web page

Path from code to running container Code and Dockerfile are converted to the image with docker building, the image is run as a container with docker run and uploaded to the register with docker push. From code to result The same path to the developer's computer and production Code app + Dockerfile Figure packed template Container = running application build run Register sharing docker build -t my-page . docker run my-page docker push Why It Is Important The image contains ALL that the app needs → The same image works identically anywhere (design, test, production).

Next - a real example with precise commands and exactly what you will see on the screen. You can track your computer if Docker is installed.

1

Prepare two files in one folder

You only need one HTML file (your page) and one Dockerfile (instruction Docker'am). There is no need to be able to program.

mana-lapa/
├── index.html      ← tava tīmekļa lapa
└── Dockerfile       ← instrukcija, kā to iepakot
2

Inscriptions Dockerfile - 2 rows

Dockerfile is always a simple text file without extension. These two lines mean "start with a finished web server" and "copy my file to where the server is looking for pages.".

FROM nginx:alpine          ← 1) izmanto gatavu web servera attēlu
COPY index.html /usr/share/nginx/html/  ← 2) iekopē tavu failu iekšā
3

Build Image - docker Build

Open the terminal in this folder and record this command. "-t my-page" gives the image the title "my-page" so that it can be found later; the last point "." means "see Dockerfile here in the current folder.".

$ docker build -t mana-lapa .
Sending build context to Docker daemon
Step 1/2 : FROM nginx:alpine
Step 2/2 : COPY index.html /usr/share/nginx/html/
Successfully tagged mana-lapa:latest
4

Launch container - docker run

"-d" starts the container in the background (the terminal remains free); "-p 8080:80" connects the port of your computer to the port of 80 inside the container (there listens nginx).

$ docker run -d -p 8080:80 mana-lapa
a1b2c3d4e5f6...  ← konteinera ID (garš, unikāls kods)
5

Look at the result

Open your browser and go to this address - see your index.html page served by nginx operating in the container.

http://localhost:8080  ← atver šo pārlūkā
6

Stop and clean when finished

docker ps shows running containers and their ID; with this ID you can stop the container and then delete it.

$ docker ps
CONTAINER ID   IMAGE       PORTS                  STATUS
a1b2c3d4e5f6   mana-lapa   0.0.0.0:8080->80/tcp   Up 2 minutes

$ docker stop a1b2c3d4e5f6
$ docker rm a1b2c3d4e5f6

What you just did

You built your first picture, launched it as a container and saw the result in the browser - that's the whole cycle. The following tabs explain each command in more detail and what to do if more than one container is needed.

Reference

Dockerfile reference, OCI Image Spec, CI/CD conveyors automatically constructs and scans images (see "Secure Development" guide).

Note

If there are other files in the folder (for example, secrets or .git), add the .dockerignore file so they don't arrive in the picture - it works like .gitignore.

Parts of each team are precisely defined

Main Docker commands

Docker Team Construction (anatomic) Command docker run -d -p 8080:80 my page divided into five parts with the precise meaning of each part - program, subcommand, flag, port mapping and image name. Structure of the team - the exact meaning of each part Let us follow the previous example: each part is explained separately so that nothing should be mentioned docker run -d -p 8080:80 mana-lapa Each part means exactly this and nothing else: docker program - Docker Command Line Tool giving all orders run sub-command 1 - "start a new container from the image' -d "detached" - works in the background, terminal remains free -p 8080:80 port mapping: KREISING SKAITLIS = your computer, LABAIS = inside container mana-lapa image name - PRECISION indicates which image to run docker < team> [guide] This structure recurs in ALL Docker teams below - the team always before flags

Container life cycle: built image → docker run → running → docker stop → stopped → docker rm → deleted. Every transition is caused directly by one team.

Images

docker build -t mana-lapa .creates an image from Dockerfile in this folder; "-t my page" gives it the name
docker imagesdisplays ALL images stored on your computer
docker pull nginx:alpinedownload the finished image "nginx" from Docker Hub (default registry)
docker push mana-lapaupload your image to the register (first need docker login)
docker rmi mana-lapadelete the image from your computer (rmi=remove image)

Containers

docker run -d -p 8080:80 mana-lapalaunch a new container in the background, your port 8080 → container port 80
docker psshow the containers operating ONLY
docker ps -ashow VISUS containers, including stopped (a = all)
docker stop IDstops the operating container (the data remains in the container)
docker exec -it ID shopen interactive command line in KONTEINER IN-USE (-it = interactive)
docker rm IDDO NOT erase a suspended container

Docker Compose

docker compose up -dcreates and launches VISUS services from compose.yaml, background
docker compose downstops and removes all services and networks (data volumes SOWAPS)
docker compose logs -ffollow ALL service logs in real time (-f = "follow"/fold)
docker compose psshows the status of compose environmental services

Diagnostics and cleaning

docker logs -f IDfollows a single container output in real time (Ctrl+C to exit)
docker inspect IDpresent full technical information (IP address, volumes, etc.)
docker statsindicates CPU/memory consumption for all operating containers
docker system pruneDRINK suspended containers and unused images - requires confirmation

What means "ID" will apply

"ID' = container identifier from docker ps column CONTAINER ID. The first 3-4 symbols (e.g. a1b2) shall be sufficient, or the container name shall be used if assigned by a -name.

Dangerous Commands

--privileged eliminates almost all isolation -- the container acquires as many rights as the host root user. Just as dangerous is to give the container access to the Docker Control Channel (/var/run/docker.sock) - this allows controlling ALL other containers and own host. Use both ONLY for a clear reason.

Multi-container environment in one file

Docker Compose - the whole environment with one team

Development of the Docker Compose environment One compose.yaml file describes several services; docker compose up creates all containers in the same network with a common data storage. One file → whole environment compose.yaml describes services, network and data; docker compose up it created compose.yaml services: web: build: . port: ["8080:80'] db: image: postgress:16 volumes: [data:/data] cache: image: red:7 other, including mixtures: needle: up -d Network: appnet web :8080 db postgress cache year volume needle docker compose up -d → 3 containers per network, db data stored in volume, down removes

Imagine your "my-page" also needs a database. Without the Compose you should manually run two "docker run," create a network and connect them. With Compose - one file, one command.

$ docker compose up -d
 Network appnet       Created
 Container app-web-1     Started
 Container app-db-1      Started
 Container app-cache-1   Started

$ docker compose ps
NAME             IMAGE          STATUS         PORTS
app-web-1        app-web        Up 5 seconds   0.0.0.0:8080->80/tcp
app-db-1         postgres:16    Up 5 seconds
app-cache-1      redis:7        Up 5 seconds

In practice

Real applications rarely have one container - usually web + database + cache. Compose describes them in one file and starts with one command; everyone automatically sees each other on the network.

Reference

Compose Specification (compose.yaml) - used for "docker compose' (v2), NE obsolete "docker-compose' (v1). Scaling, Cubanettes.

Note

Containers are temporary - database data stored volume, otherwise they disappear after "down." No secrets (passwords) shall be placed in the image and compose.yaml: used for Compose Secrets (files /run/secrets/). The environmental variables are weaker - they are seen in docker inspection and child processes.

Best practices and security

Smaller, safer, faster image

Docker best practice in three areas Recommendations in three groups - image creation, security and delivery of execution time - by international practice. Best practices and security Small image = smaller attack surface and faster start Figure - Small base image (alpine/distroless) - Multi-stage construction (less end image) - Fixes versions (nginx:1.28, no late) - .dockerignore (without unnecessary files) - One application per container - Frequently put the variable in the end of Dockerfile Time - Do not act as root (USER) - Read-only file system - Give up privileges (capabilities) - NEKAD --privileged without need - Limiting CPU/memory - Rootless mode, if possible Delivery - Scanning images (CVE) before release - Secrets outside the image - Sign pictures (origin) - Reliable base images (official) - Regularly rebuilt (new patches) - SBOM - List of ingredients OCI, NIST SP 800-190, CIS Docker Benchmark, Docker Best Practice Guidelines

A specific example - the same purpose (run the Node.js app), but one version is risky, the other safe:

Risks

FROM ubuntu:latest
COPY . /app
WORKDIR /app
RUN npm install
CMD ["node", "server.js"]

"latest" = unpredictable (variable without warning); no USER line → acts as root; no .dockerignore → secrets/.git can get to the picture.

Safe

FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
USER node
CMD ["node", "server.js"]

Fixed version (22-alpine, LTS); small base image; USER node = running without root rights; dependencies copied before code (faster rebuilding).

Why a Small Image

A smaller base image (alpine, dystroless) contains fewer packages → less vulnerability, faster download and start. Multi-stage construction throws construction tools from the final image.

Reference

NIST SP 800-190 (Application Container Security Guide), CIS Docker Benchmark, OCI, Docker Official Images.

Safety Note

The container divides the core of the host - root container is more dangerous than the VM. Undoing as root, giving up unnecessary privileges and never using --privileged without a clear need.

Dictionary

Main concepts in plain language (original and meaning).

konteiners
An isolated, lightweight application package with everything you need that divides the host core.
attēls / image
Only-to-read container template (hub) from which the containers are launched.
Dockerfile
Text instructions on how to assemble an image (base, addiction, code, startup).
apakškomanda
The second word in the team, e.g. "run" in the team docker run - determines what docker will do.
karodziņš / flag
Additional command parameter with a defisis in front (e.g. -d, -p) that changes its operation.
porta kartējums
-p 8080:80 means: your computer (8080) → container (80). The left side of a single host.
reģistrs / registry
Image storage - Docker Hub, GHCR or private.
tag
Image version designation, e.g. my-page:1.0.
volume
Permanent storage of data outside the container (overflow of its deletion).
tīkls / network
Communication between containers by service name.
Compose
Multi-container environment definition in one compose.yaml file.
Kubernetes
Container orchestrating on a scale (many cars, auto-renewal).
OCI
Open Container Initiative - standards for image and performance.
kodols / kernel
The main component of the operating system, which manages hardware and processes; the containers divide it with the host.
daemon
Docker background service (dockerd) that controls containers.
multi-stage
Construction in several stages to make the final image small (without construction tools).
distroless
Minimum baseline image without liner and package manager (smaller surface).
rootless
Docker activity without root privileges (safener).