Що таке Docker?

Docker — це платформа для запуску застосунків у контейнерах. Контейнер — це легковісне ізольоване середовище, яке містить все необхідне для роботи програми: код, бібліотеки, системні інструменти.

Контейнер vs Віртуальна машина

Найпростіше зрозуміти контейнери — порівняти їх з віртуальними машинами (VM):

┌─────────────────────────────────────────────────────────────────┐
│                    ВІРТУАЛЬНІ МАШИНИ                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────┐   ┌─────────┐   ┌─────────┐                      │
│     App A       App B       App C      <- Застосунки     │
│   ├─────────┤   ├─────────┤   ├─────────┤                      │
│     Bins/       Bins/       Bins/      <- Бібліотеки     │
│     Libs        Libs        Libs                         │
│   ├─────────┤   ├─────────┤   ├─────────┤                      │
│    Guest       Guest       Guest       <- Повна ОС       │
│      OS          OS          OS           (1-2 GB кожна) │
│   └─────────┘   └─────────┘   └─────────┘                      │
│   ┌─────────────────────────────────────┐                      │
│              Hypervisor                    <- Гіпервізор     │
│   └─────────────────────────────────────┘                      │
│   ┌─────────────────────────────────────┐                      │
│              Host OS                       <- ОС хоста       │
│   └─────────────────────────────────────┘                      │
│   ┌─────────────────────────────────────┐                      │
│              Hardware                      <- Залізо         │
│   └─────────────────────────────────────┘                      │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                       КОНТЕЙНЕРИ                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────┐   ┌─────────┐   ┌─────────┐                      │
│     App A       App B       App C      <- Застосунки     │
│   ├─────────┤   ├─────────┤   ├─────────┤                      │
│     Bins/       Bins/       Bins/      <- Тільки потрібні│
│     Libs        Libs        Libs          бібліотеки     │
│   └─────────┘   └─────────┘   └─────────┘       (50-500 MB)    │
│   ┌─────────────────────────────────────┐                      │
│            Docker Engine                   <- Docker         │
│   └─────────────────────────────────────┘                      │
│   ┌─────────────────────────────────────┐                      │
│              Host OS                       <- Спільна ОС     │
│   └─────────────────────────────────────┘                      │
│   ┌─────────────────────────────────────┐                      │
│              Hardware                      <- Залізо         │
│   └─────────────────────────────────────┘                      │
└─────────────────────────────────────────────────────────────────┘

Головна різниця: контейнери використовують ядро (kernel) хостової ОС, а VM — повну операційну систему кожна.

Характеристика VM Container
Розмір 1-50 GB 10-500 MB
Запуск Хвилини Секунди
Ізоляція Повна На рівні процесу
Використання RAM Високе Низьке
Накладні витрати Значні Мінімальні

Навіщо Docker?

Проблема без Docker

Розробник: "Все працює на моїй машині!"
     |
     +-- Python 3.11 встановлено
     +-- PostgreSQL 15 на порту 5432
     +-- Redis працює
     +-- Всі змінні середовища налаштовані
     |
     v
Сервер: "Нічого не працює..."
     |
     +-- Python 3.8 (стара версія)
     +-- PostgreSQL 14 (інша версія)
     +-- Redis не встановлено
     +-- Змінні середовища? Які?

Рішення з Docker

Розробник: docker build -t myapp .
     |
     v
[Docker Image]
     |
     +-- Python 3.11 
     +-- PostgreSQL client 
     +-- Redis client 
     +-- Всі залежності 
     +-- Змінні середовища 
     |
     v
Будь-який сервер: docker run myapp
     |
     v
"Працює ідентично скрізь!"

Основні концепції

Image (Образ)

Образ — це шаблон для створення контейнера. Як ISO-файл для встановлення ОС, тільки для застосунку.

  • Образ незмінний (immutable)
  • Складається з шарів (layers)
  • Зберігається в реєстрі (Docker Hub, GitHub Container Registry)
# Завантажити образ
docker pull nginx:alpine

# Список локальних образів
docker images

Container (Контейнер)

Контейнер — це запущений екземпляр образу. Як процес у системі, але ізольований.

  • Контейнер можна запускати, зупиняти, видаляти
  • Кожен контейнер має свою файлову систему
  • Можна запустити багато контейнерів з одного образу
┌──────────────────┐
│   Image: nginx   │  <-- Один образ
└────────┬─────────┘
         │
    ┌────┴────┐
    │         │
    v         v
┌───────┐ ┌───────┐
│ web-1 │ │ web-2 │  <-- Багато контейнерів
└───────┘ └───────┘

Docker Hub

Docker Hub — це публічний реєстр образів. Як GitHub, тільки для Docker образів.

Популярні офіційні образи:
- nginx — веб-сервер
- postgres — база даних
- python — Python середовище
- node — Node.js середовище
- redis — кеш/черга

# Знайти образ
docker search nginx

# Завантажити конкретну версію
docker pull postgres:15-alpine

Базові команди

Запуск контейнера

# Базовий запуск
docker run nginx

# З параметрами
docker run -d --name webserver -p 8080:80 nginx
#          │  │                │
#          │  │                └── порт хоста:порт контейнера
#          │  └── дати ім'я контейнеру
#          └── запустити у фоні (detached)

Робота з контейнерами

# Список запущених контейнерів
docker ps

# Всі контейнери (включно з зупиненими)
docker ps -a

# Зупинити контейнер
docker stop webserver

# Запустити зупинений контейнер
docker start webserver

# Перезапустити
docker restart webserver

# Видалити контейнер
docker rm webserver

# Видалити працюючий контейнер примусово
docker rm -f webserver

Логи та діагностика

# Логи контейнера
docker logs webserver

# Логи в реальному часі
docker logs -f webserver

# Останні 100 рядків
docker logs --tail 100 webserver

# Виконати команду в контейнері
docker exec -it webserver bash
#           │
#           └── -i (interactive) + -t (tty) = інтерактивний термінал

Робота з образами

# Список образів
docker images

# Видалити образ
docker rmi nginx:alpine

# Очистити невикористані образи
docker image prune -a

# Перевірити використання диску
docker system df

Практичний приклад: запуск Nginx

Давайте запустимо веб-сервер Nginx і побачимо його в дії.

Крок 1: Запуск

# Завантажуємо та запускаємо nginx
docker run -d --name my-nginx -p 8080:80 nginx:alpine

Що означають параметри:
- -d — запустити у фоновому режимі
- --name my-nginx — назвати контейнер "my-nginx"
- -p 8080:80 — пробросити порт 80 контейнера на порт 8080 хоста
- nginx:alpine — образ nginx на базі Alpine Linux (мінімальний)

Крок 2: Перевірка

# Перевіряємо чи працює
docker ps

# Дивимось логи
docker logs my-nginx

# Відкриваємо в браузері
curl http://localhost:8080

Крок 3: Власний контент

# Створюємо свій HTML файл
mkdir -p /tmp/mysite
echo "<h1>Привіт від Docker!</h1>" > /tmp/mysite/index.html

# Запускаємо з монтуванням директорії
docker rm -f my-nginx
docker run -d --name my-nginx \
  -p 8080:80 \
  -v /tmp/mysite:/usr/share/nginx/html:ro \
  nginx:alpine
#     │
#     └── :ro = read-only (тільки читання)

Крок 4: Заходимо всередину

# Зайти в контейнер
docker exec -it my-nginx sh

# Всередині контейнера:
ls /usr/share/nginx/html/
cat /etc/nginx/nginx.conf
exit

Крок 5: Очистка

# Зупинити та видалити
docker stop my-nginx
docker rm my-nginx

# Або одразу
docker rm -f my-nginx

Життєвий цикл контейнера

          docker pull
               │
               v
         ┌───────────┐
         │   Image   │
         └─────┬─────┘
               │ docker run
               v
         ┌───────────┐
         │  Created  │
         └─────┬─────┘
               │ docker start
               v
         ┌───────────┐    docker stop    ┌───────────┐
         │  Running  │ ───────────────>  │  Stopped  │
         └───────────┘                   └─────┬─────┘
               │                               │
               │ docker rm                     │ docker rm
               v                               v
         ┌───────────────────────────────────────┐
         │              Removed                  │
         └───────────────────────────────────────┘

Типові помилки

Порт вже зайнятий

# Помилка
Error: bind: address already in use

# Рішення: знайти що займає порт
lsof -i :8080
# або використати інший порт
docker run -p 8081:80 nginx

Контейнер одразу зупиняється

# Перевірити логи
docker logs container_name

# Частіше за все: команда в контейнері завершилась
# або помилка в конфігурації

"Permission denied" при монтуванні

# На Linux: SELinux може блокувати
docker run -v /path:/container/path:z nginx
#                                    │
#                                    └── :z для SELinux

# Або перевірити права на директорію
ls -la /path

Контейнер не бачить інші контейнери

# Контейнери повинні бути в одній мережі
docker network create mynet
docker run --network mynet --name db postgres
docker run --network mynet --name app myapp

Корисні аліаси

Додайте в ~/.bashrc або ~/.zshrc:

alias d='docker'
alias dps='docker ps'
alias dpsa='docker ps -a'
alias di='docker images'
alias dex='docker exec -it'
alias dlogs='docker logs -f'
alias dstop='docker stop $(docker ps -q)'  # Зупинити всі
alias drm='docker rm $(docker ps -aq)'      # Видалити всі зупинені

Див. також

Шлях: infrastructure/docker-basics.md

UMTC Wiki © 2026 | Ukrainian Military Tactical Communications