Що таке Docker і навіщо він потрібен?
Docker - відкрита платформа, яка пакує застосунок і його залежності в один ізольований модуль під назвою container (контейнер), щоб одне і те саме програмне забезпечення запускалось ідентично на лептопі, у CI і на проді.
Теорія
TL;DR
- Docker = формат пакування + рантайм: збираєш один раз, запускаєш всюди, де є Docker engine
- Container це процес, ізольований від хоста через можливості Linux kernel (namespaces і cgroups), а не маленька VM
- Розв'язує клас багів «у мене працює» бо рантайм їде разом з кодом
- Стандарт індустрії з виходу Docker Engine 1.0 у 2014; актуальна стабільна гілка 29.x (квітень 2026)
- Беремо коли потрібен паритет середовищ, швидкі деплої, ізоляція сервісів. Не беремо для статики і одноразових скриптів
Швидкий приклад
$ docker run -p 8080:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
e4fff0779e6d: Pull complete
2c5c0f9c49b1: Pull complete
Status: Downloaded newer image for nginx:latest
2026/04/30 10:24:01 [notice] 1#1: nginx/1.27.4Ця одна команда стягнула готовий image nginx, запустила його ізольовано від хоста і пробросила порт 80 всередині container на 8080 на лептопі. Без встановлення nginx, без конфіг-файлів, без сміття після зупинки.
Чому команди реально перейшли
До Docker задеплоїти сервіс означало мати runbook: встановити Node 16, libpng, скопіювати ось ці env-змінні, запустити міграцію. Кожне середовище дрейфувало окремо. Docker звертає це у єдиний артефакт під назвою image, який ти збираєш раз і запускаєш всюди ідентично. Жарт «у мене на компі працює» перестав бути жартом, коли деви побачили, що image, протестований локально, побітово ідентичний тому, що крутиться у проді.
Коли тягнутися за Docker
- Кілька сервісів живуть на одному хості, але потребують різних версій рантайму (Python 3.11 і Python 3.13 на одній машині)
- CI має відтворити продакшен-середовище точно
- Новачок у команді клонує репо і піднімає весь стек однією командою (
docker compose up) - Ти деплоїшся до кількох cloud-провайдерів і не хочеш бути прив'язаним до AWS-специфічного тулінгу
Коли Docker не потрібен
Статичний сайт, що йде на CDN, нічого не отримає від container. Короткий shell-скрипт, який запускається раз, не треба загортати. Embedded-системам зі строгими обмеженнями пам'яті 30 MB оверхеду відчутні. Точка беззбитковості зазвичай два-три сервіси з різними рантаймами, або CI-пайплайн, що вимагає відтворюваності. Нижче цього складність коштує більше, ніж економить консистентність.
Як це насправді запускається
Docker не є віртуальною машиною. Коли ти робиш docker run nginx, Docker daemon (dockerd) просить container runtime (containerd, далі runc) запустити процес nginx на kernel хоста. Цей процес отримує свою власну в'юху файлової системи, мережевих інтерфейсів і PID через Linux namespaces. Ліміти на CPU і пам'ять приходять з cgroups. Процес nginx думає, що він сам на машині; kernel хоста знає, що це просто ще один процес з додатковими обмеженнями. Тому container стартує за мілісекунди, а VM за десятки секунд.
Типові помилки
Сприймати container як довгоживучий сервер
# НЕПРАВИЛЬНО: заходити всередину і ставити пакети
docker exec -it mycontainer apt-get install vim
# Ці зміни зникнуть при перезапуску container.
# ПРАВИЛЬНО: запекти все потрібне у Dockerfile
FROM nginx:1.27
RUN apt-get update && apt-get install -y vimContainer задумано як замінний. Все, що ти змінюєш всередині запущеного, втрачається при наступному рестарті, якщо це не у volume.
Плутати image і container у розмові
$ docker images # список image (шаблони)
$ docker ps # список запущених container (екземпляри)
$ docker rm <id> # видалити container
$ docker rmi <id> # видалити imageImage це креслення. Container це запущена штука. У них окремі команди, і плутанина між ними коштує новачкам першої години.
Запускати все під root
# НЕПРАВИЛЬНО: дефолтний користувач root, container escape стає страшнішим
FROM node:22
COPY . /app
CMD ["node", "app.js"]
# ПРАВИЛЬНО: скинути привілегії
FROM node:22
COPY . /app
USER node
CMD ["node", "app.js"]Container поділяє kernel з хостом. Процес під root всередині залишається процесом під root, якщо вирветься з namespace.
Реальне застосування
- Netflix: деви будують і тестують microservices у Docker container, потім деплоять у AWS. Ідентичність image від лептопа до проду прибрала цілий клас «deploy regression» багів.
- Spotify: роками крутили самописний оркестратор (Helios) поверх Docker, перш ніж мігрувати на Kubernetes. Створення сервісу, що раніше займало годину, після міграції стало хвилинами.
- PayPal, Uber, Airbnb: Docker як стандартний CI-артефакт. PR-білд генерує image, інтеграційні тести бігають проти нього, image заливається у registry і йде у деплой.
- Локальна розробка:
docker compose upпіднімає Postgres, Redis і застосунок одразу замістьbrew installп'яти речей і пам'ятати версії.
Одного разу я два дні шукав мисматч між Node 16 на dev і Node 14 на проді, який зник того дня, коли ми загорнули обидва у однакові Docker images. Саме для цього класу багів Docker і існує.
Питання для поглиблення
Q: Якщо Docker не VM, чому відчуття таке саме?
A: Бо ізоляція достатньо хороша, щоб процеси всередині не бачили нічого зовні. Але це процес на kernel твого хоста, а не гостьова операційна система. Саме тому container запускається у мілісекундах, а VM у десятки секунд.
Q: Що Docker реально ставить на машину?
A: Docker Engine. Це dockerd (фоновий daemon), docker (CLI client), containerd (власне container runtime) і кілька CLI-помічників. На Mac і Windows він пакує маленьку Linux VM, бо container'ам потрібен Linux kernel.
Q: Docker це те саме що Kubernetes?
A: Ні. Docker будує і запускає окремі container на одному хості. Kubernetes оркеструє багато container на багатьох хостах і вирішує речі типу рестартів, rolling-апдейтів і service discovery. Більшість продакшен-команд використовують обидва.
Q: Чому деякі команди беруть Podman або nerdctl замість docker?
A: Той самий OCI image-формат, ті самі workflow, але без daemon (Podman) або тонший стек (nerdctl лежить прямо на containerd). Має значення у регульованих середовищах, де живий root-daemon сам собою проблема для безпеки.
Q: (Senior) Коли Docker стає неправильним інструментом?
A: Коли оверхед і складність переважують виграш у консистентності. Статичний сайт за CDN нічого не отримає. Команда з одним Go-бінарником і одним сервером отримує дуже мало. Точка беззбитковості зазвичай два-три сервіси з різними рантаймами, або CI-пайплайн, що вимагає відтворюваності. Нижче цього ти платиш за можливості, які не використаєш.
Приклади
Запуск одноразової бази для локальної розробки
$ docker run -d --name pg \
-e POSTGRES_PASSWORD=devpass \
-p 5432:5432 \
postgres:16
# Підключення з застосунку
$ psql -h localhost -U postgresБез встановлення Postgres на хост, без сервісу, який треба підтримувати. Зупинка і видалення docker rm -f pg. Хочеш Postgres 17 наступного місяця? Заміни 16 на 17. Жодних конфліктів, жодних залишків даних, поки явно не попросиш.
Пакування власного Node-застосунку
# Dockerfile
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
USER node
EXPOSE 3000
CMD ["node", "server.js"]$ docker build -t myapp:0.1 .
$ docker run -p 3000:3000 myapp:0.1Тепер будь-який тіммейт робить git pull && docker build -t myapp:0.1 . && docker run -p 3000:3000 myapp:0.1 і отримує ту саму версію Node, ті самі залежності, той самий рантайм, що у проді. Dockerfile це рецепт збірки; image це результат; container це запущений екземпляр.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.
Коментарі
Ще немає коментарів