Як працює Docker: контейнери, образи, шари і реєстри
Модель Docker без магії: чим контейнер відрізняється від віртуалки, namespaces і cgroups, образ і контейнер, шари, теги й digest, реєстри та архітектура Docker Engine.
Навіщо Docker
Класична проблема: «у мене працює, а на сервері — ні». Інша версія Python, бракує системної бібліотеки, конфлікт залежностей двох застосунків на одному сервері. Docker вирішує це так: застосунок пакується разом з усім оточенням (рантайм, бібліотеки, налаштування) в образ, і цей образ однаково запускається на ноутбуці, у CI і на проді.
Що це дає на практиці:
- Відтворюваність — той самий образ, що пройшов тести, їде в прод.
- Ізоляція — десять застосунків на одному сервері не заважають один одному.
- Швидкість — контейнер стартує за секунди, а не за хвилини.
- Стандарт — один формат для будь-якої мови: Kubernetes, CI, хмари й PaaS (Dokploy, Coolify, Render) приймають образ.
АктуальністьРозділ написано для Docker Engine 29.x і Docker Desktop 4.x (жовтень 2026). Команди
docker compose(з пробілом) і BuildKit — стандарт з 2023 року; старийdocker-compose(з дефісом) більше не підтримується.
Контейнер — це не віртуальна машина
Віртуальна машина емулює цілий комп'ютер: свої віртуальні диски, своє ядро ОС, свій завантажувач. Важить гігабайти, стартує хвилини.
Контейнер — це звичайний процес Linux, якого ядро ізолювало від решти системи. Ядро спільне з хостом, тож контейнер важить мегабайти й стартує за частки секунди. Переконайтеся самі:
docker run -d --name web nginx:stable-alpine
ps aux | grep "nginx: master" # на хості видно процес nginx!root 48213 0.0 0.0 9220 6144 ? Ss 14:02 0:00 nginx: master process nginx -g daemon off;Ізоляцію забезпечують два механізми ядра Linux:
| Механізм | Що робить | Приклад |
|---|---|---|
| namespaces | обмежують, що процес бачить | свої PID (процес бачить себе як PID 1), мережа, файлова система, hostname, користувачі |
| cgroups | обмежують, скільки процес споживає | --memory 512m, --cpus 1.5, ліміт кількості процесів |
Наслідок спільного ядраКонтейнер ізольований слабше за ВМ: вразливість ядра зачіпає всіх. І ще: Linux-контейнери потребують ядра Linux. Тому Docker Desktop на Windows і macOS запускає маленьку Linux-віртуалку (див. «Встановлення і налаштування»).
Образ і контейнер
Найважливіша пара понять:
| Образ (image) | Контейнер (container) | |
|---|---|---|
| Що це | шаблон: файлова система + налаштування запуску | запущений (або зупинений) екземпляр образу |
| Змінюється? | ні, лише для читання | так, має свій шар для запису |
| Аналогія | клас у програмуванні, ISO-образ диска | об'єкт класу, встановлена система |
| Скільки | один | скільки завгодно з одного образу |
| Команди | docker build, pull, push, images |
docker run, ps, stop, rm |
docker pull redis:7-alpine # завантажили образ
docker run -d --name cache1 redis:7-alpine # контейнер №1
docker run -d --name cache2 redis:7-alpine # контейнер №2 з того самого образу
docker psCONTAINER ID IMAGE COMMAND STATUS NAMES
3f1a2b4c5d6e redis:7-alpine "docker-entrypoint.s…" Up 3 seconds cache2
9e8d7c6b5a4f redis:7-alpine "docker-entrypoint.s…" Up 5 seconds cache1Шари: з чого складається образ
Образ — не один великий архів, а стос шарів. Кожна інструкція RUN, COPY, ADD у Dockerfile додає шар зі змінами файлової системи. Контейнер отримує поверх них свій тонкий шар для запису.
Чому це важливо:
- Економія місця і трафіку. Десять образів на базі
python:3.13-slimзберігають базовий шар один раз.docker pullзавантажує лише шари, яких у вас ще немає. - Швидка збірка. Незмінені шари беруться з кешу — про це в нотатці «Dockerfile».
- Дані в контейнері тимчасові. Шар контейнера видаляється разом із контейнером. Базу даних без тому втратите з першим
docker rm.
docker history nginx:stable-alpine # шари образу і їхні розміриІм'я образу: реєстр, репозиторій, тег, digest
Повне ім'я образу складається з частин:
ghcr.io/olena/notes-app:1.4.0@sha256:9f86d081884c7d65...
└──┬──┘ └───────┬─────┘ └─┬─┘ └──────────┬──────────┘
реєстр репозиторій тег digest| Частина | Значення за замовчуванням | Приклад |
|---|---|---|
| реєстр | docker.io (Docker Hub) |
ghcr.io, registry.gitlab.com, 123.dkr.ecr.eu-central-1.amazonaws.com |
| простір імен | library (офіційні образи) |
olena, bitnami |
| тег | latest |
1.4.0, 17-alpine, stable |
| digest | — | sha256:… — незмінний відбиток вмісту |
Тобто nginx — це насправді docker.io/library/nginx:latest.
Тег можна перезаписати, digest — ніТег — лише ярлик, автор може в будь-який момент перевісити
nginx:stableна новий образ.latestне означає «найновіший» — це просто тег за замовчуванням. Для відтворюваних збірок і продакшену вказуйте конкретну версію (postgres:17.6-alpine), а для максимальної гарантії — digest:postgres@sha256:….
Реєстри
Реєстр (registry) — сховище образів, як GitHub для коду.
| Реєстр | Коли використовувати |
|---|---|
| Docker Hub | офіційні образи (nginx, postgres, node), публічні образи |
GitHub Container Registry (ghcr.io) |
ваш код на GitHub — образи поряд, права з GitHub |
| GitLab Container Registry | ваш код на GitLab |
| AWS ECR, Google Artifact Registry, Azure ACR | застосунок живе в цій хмарі |
Harbor, власний registry:2 |
закрита мережа, повний контроль |
docker login ghcr.io # увійти (токен замість пароля)
docker tag notes-app:1.4.0 ghcr.io/olena/notes-app:1.4.0
docker push ghcr.io/olena/notes-app:1.4.0
docker pull ghcr.io/olena/notes-app:1.4.0Як влаштований Docker усередині
| Компонент | Роль |
|---|---|
| docker (CLI) | програма, у яку ви пишете команди; сама нічого не запускає |
| dockerd | демон: приймає команди через сокет /var/run/docker.sock, керує образами, мережами, томами |
| containerd | керує життєвим циклом контейнерів (його ж використовує Kubernetes) |
| runc | низькорівнево створює процес з namespaces і cgroups |
| BuildKit | рушій збірки образів (docker build) |
Усе це відповідає відкритим стандартам OCI (Open Container Initiative). Тому образ, зібраний Docker, запуститься в Podman, containerd чи Kubernetes, і навпаки.
docker.sock = rootХто може писати в
/var/run/docker.sock, той фактично root на хості: можна запустити контейнер із примонтованим/і зробити з системою що завгодно. Тому членство в групіdockerі монтування сокета в контейнери (-v /var/run/docker.sock:...) — питання безпеки, а не зручності.
Альтернативи
- Podman — сумісний CLI (
alias docker=podman), без демона, rootless за замовчуванням. Популярний на RHEL/Fedora. - containerd + nerdctl — легший стек без Docker Engine.
- Kubernetes — не замінює Docker, а оркеструє контейнери на багатьох серверах; образи для нього збирають тим самим Docker.
Коротко
- Контейнер — ізольований процес на спільному ядрі, а не ВМ.
- Образ — незмінний шаблон зі стосу шарів; контейнер — його запущений екземпляр зі своїм шаром для запису.
- Дані в шарі контейнера зникають разом із контейнером — для даних є томи.
- Повне ім'я образу:
реєстр/репозиторій:тег@digest;latest— пастка. - Доступ до
docker.sockдорівнює правам root.
Збережіть статтю собі
Увійдіть, щоб імпортувати її у власні нотатки, відмічати вивчене, ставити лайки й питати спільноту. Реєстрація безкоштовна: вхід через Google займає кілька секунд.
Увійти через Google Інші способи входу