Контейнерне середовище розробки багатокомпонентних веб-застосунків прийшло на зміну платформам, побудованим на основі віртуальних машин. Її застосування дозволяє уникнути багатьох проблем, пов’язаних із спільним використанням машинних ресурсів та їх економією.
Однією з найпоширеніших платформ такого типу є система Docker, що забезпечує наявність повноцінного контейнерного середовища, придатного для розробки та тестування багатокомпонентних розподілених застосунків. Розглянемо питання, пов’язані з установкою програми на сервері Ubuntu, і продемонструємо деякі її можливості на практиці.
Способи побудови програмного середовища для роботи веб-застосунків
Для роботи поштових і веб-серверів, сайтів та будь-яких інших інтернет-ресурсів необхідна наявність підготовленого програмного середовища, що має певні характеристики. З часом виділилися три основні напрями побудови такого середовища:
- Традиційне середовище, засноване на безпосередньому використанні фізичних ресурсів комп’ютера;
- Віртуальні машини;
- Контейнерні середовища.
Основним недоліком використання традиційного середовища є її велика ресурсомісткість і, відповідно, витратність, що обмежує можливості її широкого застосування у зв’язку з постійно зростаючими ресурсними вимогами програмного забезпечення.
Віртуалізація програмного середовища дозволила на деякий час зняти проблему нестачі ресурсів, що, наприклад, відобразилося у появі безлічі типів віртуальних серверів на хостинг-платформах. VPS-сервери в значній мірі здатні конкурувати з фізичними серверами при мінімальному рівні використаних ресурсів.
Контейнерні середовища з’явилися як відповідь на постійно зростаючі запити щодо ефективності використання фізичних ресурсів комп’ютера при розробці багатокомпонентних розподілених веб-застосунків. На відміну від віртуальних машин, віртуалізація середовища тут реалізується на рівні операційної системи (ОС), а не фізичних ресурсів комп’ютера. Причому контейнери є більш «легковагими» і «гнучкими» в контексті використання спільних ресурсів операційної системи.
В результаті стало можливим отримати в межах однієї фізичної машини або VPS-сервера більшу кількість «незалежних» серед функціонування та/або розробки багатокомпонентних веб-застосунків.
На Рисунку 1. представлені розглянуті нами варіанти організації програмного середовища: традиційна (Traditional Deployment), віртуальна (Virtualized Deployment) і контейнерна (Container Deployment).

Рисунок 1. Види програмних серед виконання веб-застосунків.
Програмний інструмент Docker
На ринку програмного забезпечення присутня велика кількість засобів створення контейнерних серед виконання застосунків, однак далеко не всі з них відповідають вимогам Міжнародного стандарту OCI (Open Container Initiative). Він визначає формальні правила реалізації віртуальної середовища на рівні операційної системи, які описані в двох специфікаціях. Одна зі специфікацій формалізує правила створення та використання загальної контейнерної середовища Container Runtime (див. Рисунок 1), а інша визначає правила роботи з образами (image) — створення, обробка тощо.
Контейнери замінюють собою віртуальні машини, маючи власне середовище виконання, ресурси та можливості налаштування параметрів конфігурації. Їх активація в Docker відбувається одразу після запуску спеціального шаблону або образу, який попередньо має бути завантажений з репозиторію або створений локально за допомогою спеціальної команди.
Платформа Docker відповідає всім вимогам стандарту OCI і може бути використана для роботи в середовищі більшості відомих ОС — Windows, MacOS, Linux тощо. Програма випускається в двох виконаннях — для комерційного використання (Enterprise) та «вільна» версія (CE), яка стала доволі популярною на платформах хостинг-провайдерів. Ми тут будемо використовувати саме цю версію програми як найбільш доступну.
Практичне використання CE Docker
Процес ознайомлення з програмою розіб’ємо на кілька етапів, що дозволить сконцентруватися на кожному з напрямків. Це такі етапи:
● Підготовка програмного середовища Ubuntu для встановлення Docker;
● Встановлення та розгортання;
● Ознайомлення зі вбудованою системою підтримки користувача;
● Робота з контейнерами.
Здійснимо послідовне виконання кожного з етапів.
Підготовка програмного середовища Ubuntu для встановлення Docker
Спочатку оновимо індекс пакетів нашої системи з репозиторію Ubuntu. Для цього введемо таку команду в командному рядку термінала:
$ sudo apt update

Як бачимо, може бути оновлено 51 пакет. Ініціюємо цю процедуру за допомогою наступної команди:
$ apt list –upgradable


Оновлення пакетів пройшло успішно.
Тепер встановимо програмні пакети, необхідні для забезпечення безперешкодної роботи протоколу, який керує завантаженнями через мережу. Для цього введемо в терміналі:
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common

Пакети успішно встановлені.
Завантажимо програмний ключ із Docker-репозиторію:
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –

У результаті ключ було завантажено на наш сервер, про що свідчить вихід команди (OK).
Щоб мати можливість здійснювати завантаження з Docker-репозиторію, необхідно додати його до списку дозволених джерел даних для нашого apt-протоколу. Це можна зробити за допомогою наступної команди:
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"

Список сформовано. Тепер можна переходити до встановлення програми.
Встановлення та розгортання
Ініціюємо процес розгортання Docker CE за допомогою наступної команди:
$ sudo apt install docker-ce

Підтверджуємо свою згоду на продовження встановлення, натиснувши клавішу Y (Yes).
Підсумкове вікно результатів виконання команди наведено нижче.

Можна переконатися, що програма була успішно встановлена в системі.
Перевіримо її статус. Для цього введемо в терміналі:
$ sudo systemctl status docker

Вихід команди:
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2024-02-02 17:44:37 UTC; 1 week 6 days ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 779607 (dockerd)
Tasks: 16
Memory: 33.3M
CPU: 4min 13.066s
CGroup: /system.slice/docker.service
└─779607 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Результати показують, що Docker-машину (контейнерне середовище) створено; демон сервісу запущено (active); PID процесу: 779607.
Тепер контейнерне середовище готове до роботи.
Ознайомлення з вбудованою системою підтримки користувача
Як і будь-яка інша програмна система, Docker надає низку вбудованих засобів, необхідних для його освоєння. Скористаймося ними.
Спочатку виведемо список усіх доступних користувачу команд для керування контейнерним середовищем і Docker-образами. Для цього введемо в командному рядку термінала:
$ docker

Опишемо найважливіші з основних Docker-команд:
- run – створення й запуск контейнера з наявного образу;
- exec – виконання команд у вже активному контейнері;
- ps – виведення списку активних контейнерів;
- build – створення образу з Docker-файлу;
- pull – завантаження образу з репозиторію;
- images – виведення списку образів, що вже є в системі.
Кожна з наведених команд має власні параметри, які використовуються під час її запуску. Переглянемо, наприклад, параметри загальної команди build. Це можна зробити за допомогою такої конструкції:
$ docker build --help

Як бачимо, команда має багато опцій для використання у різних випадках.
Щоб отримати повний набір даних про створене програмне середовище, можна скористатися наступною командою:
$ docker info

Вивід команди:
Client: Docker Engine - Community
Version: 25.0.2
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.12.1
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.24.5
Path: /usr/libexec/docker/cli-plugins/docker-compose
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 1
Server Version: 25.0.2
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Як бачимо, інформація про програмне середовище розділена на дві частини — клієнтську та серверну.
У клієнтській частині вказано версію Docker-машини, режим роботи, список установлених плагінів, їхні версії та розташування.
У серверній частині, зокрема, містяться дані про контейнери, образи, тип файлової системи та встановлені для неї драйвери.
Усе це дає повну картину конфігурації програмного середовища.
Робота з контейнерами в Docker-середовищі
Для можливості запуску контейнера необхідно мати його образ, який можна або завантажити з публічного репозиторію, або створити за допомогою спеціальної команди. Розглянемо перший варіант.
Припустімо, нам потрібен контейнер, що містить інтерпретатор мови Python для роботи з Python-додатками. Спершу переглянемо наявні образи Python у публічному репозиторії:
$ docker search python
Можна переконатися, що в репозиторії є багато образів, пов’язаних із цією мовою. Три з них є офіційними: python, pypy і hylang. Для нас найкраще підходить образ із назвою python.
Завантажимо його на наш сервер за допомогою команди:
$ docker pull python

Тепер цей образ знаходиться на нашому сервері. Перевіримо це, а заодно дізнаємось, чи є інші образи в системі.
Перегляд наявних образів
Введемо в терміналі:
$ docker images
Вивід команди:
DESCRIPTION TAG IMAGE ID CREATED SIZE
python latest a3aef63c6c10 9 days ago 1.02GB
gcr.io/k8s-minikube/kicbase v0.0.42 dbc648475405 3 months ago 1.2GB
Як бачимо, на нашому сервері є два образи, один з яких ми щойно завантажили. Команда вивела їхні атрибути: назву, тег, ідентифікатор, час створення та розмір. Ідентифікатор дозволить нам у майбутньому керувати контейнером.
Запуск контейнера на основі Python-образу
Активуємо контейнер на базі образу python за допомогою наступної команди:
$ docker run -it python

Параметр -it дозволяє увімкнути інтерактивний режим роботи з контейнером.
У результаті ми отримали доступ до інтерпретатора мови Python, де можемо вводити потрібні команди.
Наприклад, введемо команду для переходу до інтерактивної довідки Python:
>>> help()

Натискаємо комбінацію клавіш Ctrl + C, щоб вийти з довідки та повернутись до інтерпретатора.

Повертаємося до командного рядка термінала:
>>> exit()

Перегляд статусу контейнерів
Під час роботи в контейнерному середовищі може накопичуватись багато контейнерів. Щоб переглянути їхній статус, скористаємося командою:
$ docker ps -a

У списку бачимо наш контейнер зі статусом Exited (0) — це означає, що він неактивний.
Зверніть увагу на наявність двох ідентифікаторів:
- числового (9b91b4cb047e)
- символьного (eager_morse)
За допомогою будь-якого з них можна керувати контейнером.
Щоб переглянути лише активні контейнери, введемо:
$ docker ps
Результат очевидний — список порожній.
Повторний запуск контейнера
Знаючи ідентифікатор, можна знову запустити контейнер:
$ docker start 9b91b4cb047e
Перевіримо список активних ресурсів:
$ docker ps
Можемо переконатися, що контейнер знову активний.
Щоб зупинити його, скористаємося символьним іменем:
$ docker stop eager_morse

Перевіримо активні ресурси ще раз:
$ docker ps

Список знову порожній — отже, тип ідентифікатора (цифровий чи символьний) не має значення.
Створення нового образу з модифікованого контейнера
Створимо новий образ на основі умовно зміненого контейнера python. Для цього введемо:
$ docker commit -m "Modify Python" -a "Admin" 9b91b4cb047e new_python
Тут:
- new_python — довільне ім’я створюваного образу,
- Admin — ім’я користувача.

Перевірка результату
Переглянемо список образів, зареєстрованих у системі:
$ docker images

У списку з’явився новий шаблон з іменем new_python, як і очікувалося.
Висновок
Розглянуті можливості Docker-середовища є лише базовими.
Насправді вони набагато ширші й дозволяють виконувати складні маніпуляції з об’єктами віртуального середовища, проте детальне їх вивчення виходить за межі цієї статті.
