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

Ceļakarte no fiziskiem serveriem līdz konteineru orķestrēšanai Seši soļi izvietošanas attīstībā - fiziskie serveri, virtuālās mašīnas, konteiners, attēls un reģistrs, Docker Compose un orķestrēšana - ar pieaugošu drošības nozīmi virzienā uz produkciju. No servera līdz konteineru infrastruktūrai Pelēkais - pirms Docker · krāsainais - šī ceļveža tēmas 1 Fiziskie serveri viena lietotne 2 Virtuālās mašīnas vairākas OS 3 Konteiners kopīgs kodols 4 Attēls + reģistrs iepako, koplieto 5 Compose daudz konteineru 6 Orķestrēšana mērogs, K8s Laiks · briedums · mērogs Drošība: jo tuvāk produkcijai, jo kritiskāka izolācija · uzticami un skenēti attēli · noslēpumi ārpus attēla · tīkla segmentācija Šis ceļvedis: konteiners → attēls → komandas → Compose → drošība

How to Read the Guide

Roadmap shows why the containers were born (VM was 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

Virtuālās mašīnas un konteineri salīdzinājums Pa kreisi virtuālās mašīnas, kur katrai ir sava pilna operētājsistēma; pa labi konteineri, kas dala vienu resursdatora kodolu un tāpēc ir vieglāki. Virtuālā mašīna vs konteiners Konteineri dala resursdatora kodolu - tāpēc vieglāki un ātrāki Virtuālās mašīnas Lietotne A Lietotne B Lietotne C Viesa OS Viesa OS Viesa OS Hipervizors Infrastruktūra Konteineri Lietotne A Lietotne B Lietotne C Bibliotēkas Bibliotēkas Bibliotēkas Docker Engine Resursdatora OS - viens kopīgs kodols Infrastruktūra savs kodols katrai VM = spēcīga izolācija, bet smags kopīgs kodols = viegls, bet vājāka izolācija Drošība: kopīgs kodols → izrāviens (escape) var apdraudēt resursdatoru

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) - standards for image and execution time · NIST SP 800-190 · Linux namespaces / groups · Docker / containerd.

Two main concepts

Image = Template · Container = Operating instance

Attēls, reģistrs un konteiners Attēls tiek lejupielādēts no reģistra un ir tikai lasāms slāņu kopums; docker run izveido konteineru, kas ir attēls plus rakstāms slānis. Attēls → konteiners Attēls = recepte (veidne) · konteiners = gatavs ēdiens (darbojošās instance) Reģistrs Docker Hub · GHCR · privāts Attēls (image) - tikai lasāms slānis: lietotnes kods slānis: bibliotēkas slānis: izpildvide slānis: minimāla bāzes sistēma Konteiners - darbojas rakstāms slānis lietotnes kods (lasāms) bibliotēkas (lasāms) izpildvide (lasāms) bāzes OS (lasāms) docker pull docker run Viens attēls → daudz konteineru · rakstāmais slānis pazūd, kad konteineru dzēš

Application

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) · Picture 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

Ceļš no koda līdz darbojošās konteineram Kods un Dockerfile tiek pārvērsti attēlā ar docker build, attēls tiek palaists kā konteiners ar docker run un augšupielādēts reģistrā ar docker push. No koda līdz rezultātam Viens un tas pats ceļš uz izstrādātāja datora un ražošanā Kods lietotne + Dockerfile Attēls iepakota veidne Konteiners = darbojošās lietotne build run Reģistrs koplietošana docker build -t mana-lapa . docker run mana-lapa docker push Kāpēc tas ir svarīgi Attēls satur VISU, kas lietotnei vajadzīgs → tas pats attēls darbojas identiski jebkur (izstrādē, testā, ražošanā).

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). No programming is required.

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 the image (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 komandas uzbūve (anatomija) Komanda docker run -d -p 8080:80 mana-lapa sadalīta piecās daļās ar precīzu katras daļas nozīmi - programma, apakškomanda, karodziņš, porta kartējums un attēla nosaukums. Komandas uzbūve - katrai daļai precīza nozīme Turpinām iepriekšējo piemēru - katra daļa skaidrota atsevišķi, lai nekas nav interpretējams docker run -d -p 8080:80 mana-lapa Katra daļa nozīmē tieši šo un neko citu: docker programma - Docker komandrindas rīks, ar kuru dod visas pavēles run apakškomanda - "palaid jaunu konteineru no attēla" -d karodziņš "detached" - darbojas fonā, terminālis paliek brīvs -p 8080:80 porta kartējums: KREISAIS_SKAITLIS = tavs dators, LABAIS = konteinera iekšpuse mana-lapa attēla nosaukums - PRECĪZI norāda, KURU attēlu palaist docker <komanda> [karodziņi] [arguments] Šī uzbūve atkārtojas VISĀS Docker komandās zemāk - komanda vienmēr pirms karodziņiem

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

Docker Compose vides izveide Viens compose.yaml fails apraksta vairākus servisus; docker compose up izveido visus konteinerus vienā tīklā ar kopīgu datu glabātuvi. Viens fails → visa vide compose.yaml apraksta servisus, tīklu un datus; docker compose up to izveido compose.yaml services: web: build: . ports: ["8080:80"] db: image: postgres:16 volumes: [data:/data] cache: image: redis:7 volumes: data: up -d Tīkls: appnet web :8080 db postgres cache redis volume data docker compose up -d → 3 konteineri vienā tīklā · db dati glabājas volume · down noņem

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

Application

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." Secrets (passwords) are passed through environmental variables, not in the file.

Best practices and security

Smaller, safer, faster image

Docker labākā prakse trīs jomās Ieteikumi trīs grupās - attēla veidošana, izpildlaika drošība un piegāde - pēc starptautiskās prakses. Labākā prakse un drošība Mazs attēls = mazāka uzbrukuma virsma un ātrāks starts Attēls · Mazs bāzes attēls (alpine/distroless) · Multi-stage būve (mazāks gala attēls) · Fiksē versijas (nginx:1.27, ne latest) · .dockerignore (bez liekiem failiem) · Viena lietotne uz konteineru · Biežāk mainīgo liec Dockerfile beigās Izpildlaiks · Nedarbini kā root (USER) · Tikai-lasāma failu sistēma · Atmet liekās privilēģijas (capabilities) · NEKAD --privileged bez vajadzības · Ierobežo CPU/atmiņu · Rootless režīms, ja iespējams Piegāde · Skenē attēlus (CVE) pirms izlaišanas · Noslēpumi ārpus attēla · Paraksti attēlus (izcelsme) · Uzticami bāzes attēli (oficiālie) · Regulāri pārbūvē (jaunie ielāpi) · SBOM - sastāvdaļu saraksts OCI · NIST SP 800-190 · CIS Docker Benchmark · Docker labākās prakses vadlīnijas

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:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
USER node
CMD ["node", "server.js"]

Fixed version (20-alpine); 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
the template (s) of the container from which the containers are launched.
Dockerfile
text instructions on how to assemble an image (base, addiction, code, startup).
apakškomanda
second name of the team, e.g. "run" in the team docker run - determines what docker will do.
karodziņš / flag
additional command parameter with 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.
būves konteksts
the folder used by Docker to build the image - usually indicated by point (.) at the end of the team.
reģistrs / registry
image storage - Docker Hub, GHCR or private.
tags
image version designation, e.g. man-page:1.0.
volume
a permanent storage outside the container (overflow of its erasure).
bind mount
attracting the host folder into the container (often developing).
tīkls / network
communication of containers by service name.
Compose
multi-container environmental definition in one compose.yaml file.
Kubernetes
container orchestrating on a scale (many machines, auto-renewal).
OCI
Open Container Initiative - standards for image and performance.
kodols / kernel
the basic component of the operating system that manages hardware and processes; the containers share it with the host.
daemon
Docker background service (dockerd) that controls containers.
ephemeral
temporary - the container can be destroyed and re-created at any time.
multi-stage
construction in several stages so that the final image is small (without construction tools).
distroless
minimum baseline image without liner and package manager (smaller surface).
rootless
Docker activity without root privileges (safener).