1. Одного слова «Docker» мало
Є дуже короткий тест на ясність мислення. Якщо на будь-яку проблему ви кажете «Docker зламався», це означає, що ви ще не дійшли до потрібного рівня точності. Можливо, зламався зовсім не Docker. Можливо, ви дивитеся на застарілий image. Можливо, контейнер стартує і одразу завершується. Можливо, образ сам по собі нормальний, але середовище в Compose описано неправильно. А можливо, ви просто плутаєте місце зберігання артефакта з місцем запуску.
Точні слова потрібні не для краси. Вони потрібні, щоб бачити, на якому рівні виникла проблема. У застосунку історія майже та сама: якщо все називати словом «бекенд», ви втратите різницю між controller, service, repository, database і network. Тут усе так само: одне спільне слово робить діагностику туманною.
Отже, далі тримаємо в голові чотири сутності. image — це підготовлений артефакт запуску. container — реальний живий запуск із цього артефакта. registry — місце, де образи зберігаються і звідки їх можна забрати. Compose — опис середовища, де кільком сервісам потрібно жити поруч. Поки цього рівня точності достатньо.
2. image: підготовлений артефакт запуску
Тут найзручніше порівняння для Java-розробника дуже просте. image схожий не на «запущений сервер», а радше на артефакт, готовий до запуску. Він ближчий до jar, ніж до живого процесу. Образ можна зберігати, передавати, версіонувати, публікувати, завантажувати. Але сам по собі він ще нічого не «робить».
Технічно назва образу часто виглядає приблизно так:
# Назва образу у форматі: <назва_образу>:<тег>
catalog-service:1.0
# Де "1.0" — це тег (часто версія/варіант збирання), щоб розрізняти образи
Це не команда і не контейнер. Це просто ідентифікатор артефакта. Поки ви бачите таку назву, у вас ще немає «працюючого застосунку». У вас є підготовлена форма, яку потім можна запустити.
Ще одна важлива думка: образ сам по собі не дорівнює середовищу виконання. Він ближчий до «упакованого способу запустити сервіс», ніж до самого сервісу в дії. Саме тому фраза «образ працює» звучить неточно. Працювати починає вже інший об’єкт — container.
3. container: реальний запуск із image
Контейнер — це момент, коли артефакт перестає бути просто заготовкою і запускається. Сервіс усередині контейнера пише логи, відкриває HTTP-порт, живе як процес, завершується, отримує сигнали, інколи падає. Тобто контейнер — це вже середовище виконання, а не просто підготовка до нього.
На старті добре працює класична аналогія «клас і об’єкт». Вона не ідеальна, але першу плутанину знімає:
// "Шаблон" (аналог image): сам по собі нічого не "виконує", це опис
class CatalogTemplate {
}
// Екземпляр (аналог container): конкретний "запуск" за шаблоном
CatalogTemplate first = new CatalogTemplate();
// Другий незалежний екземпляр із того самого шаблону (як другий container із того самого image)
CatalogTemplate second = new CatalogTemplate();
Один шаблон може породити кілька екземплярів. Так само один image може породити кілька container. Аналогія не буквальна, але вона добре прибирає першу плутанину: образ і контейнер — не одне й те саме.
Для курсу це особливо важливо, тому що далі ми постійно мислитимемо в категоріях «один і той самий образ, але різні варіанти конфігурації середовища виконання». Якщо ці два слова злиплися в голові, тема зовнішньої конфігурації, Compose і повторних запусків одразу починає розповзатися. Тому краще від самого початку спокійно закріпити: image — це програма на диску, container — це вже працююча програма.
4. registry: сховище образів
З registry найчастіше плутаються тому, що саме слово звучить трохи розпливчасто. Через це виникає міф, ніби registry — це щось на кшталт місця, де застосунок уже живе й працює. Насправді це просто сховище образів. Уявіть склад, звідки образ можна взяти та куди його можна покласти. Жодного середовища виконання там автоматично не з’являється.
Для світу Java тут дуже близька аналогія — репозиторій бібліотек. Maven Central або корпоративний Nexus зберігають jar-артефакти, але не «запускають» їх. Вони лише роблять їх доступними. З registry рівно та сама логіка: він зберігає образи й дає змогу доставляти їх туди, де ви вже створюватимете контейнери.
Таке розрізнення потім дуже виручає. Якщо ви розумієте, що registry відповідає за зберігання та доставлення, то перестаєте шукати в ньому те, чого там немає: логи, порти, життєвий цикл сервісу, мережеві симптоми. Усе це вже не про registry, а про container і його середовище.
5. Compose: опис середовища, де сервісам жити разом
Compose варто сприймати як рівень вище, ніж просто «запуск одного контейнера». Він описує локальне середовище: які контейнери у нас є, з яких образів вони стартують, як називаються, як пов’язані, які параметри отримують. Це особливо важливо у світі бекенду, де дуже швидко виявляється, що одного застосунку мало — поруч потрібні база, кеш, брокер і ще кілька технічних залежностей.
Мінімальний фрагмент такого опису може виглядати так:
services: # кореневий розділ зі списком сервісів (контейнерів) у цьому середовищі
app: # імʼя сервісу (логічна назва в compose), не обовʼязково збігається з назвою image
image: catalog-service:1.0 # який image використовувати для запуску контейнера цього сервісу
Тут видно головне: Compose посилається на образ, але не замінює його. Compose не дорівнює image. Він описує, як цей image бере участь у локальному середовищі. І якщо пізніше поруч з’явиться PostgreSQL, Redis або RabbitMQ, це все буде вже продовженням тієї самої моделі, а не новою магією.
Ще одна практична деталь важлива вже сьогодні: канонічна назва головного файла в курсі — compose.yaml. Не тому, що без цього світ розвалиться, а тому, що єдина базова назва прибирає зайву плутанину в репозиторії та прикладах.
6. Як ці чотири сутності пов’язані між собою
Іноді одна невелика таблиця корисніша за довге пояснення. Нижче — компактна карта, до якої можна повертатися протягом усього курсу, якщо терміни починають змішуватися:
| Запитання | Правильна сутність |
|---|---|
| Що ми підготували до запуску? | image |
| Що зараз реально працює як процес? | container |
| Де зберігається і звідки доставляється образ? | registry |
| Як описати локальний стек із кількох сервісів? | Compose |
А тепер — дуже короткий зв’язок в один ряд. Проєкт і код приводять вас до образу. Із цього образу створюється контейнер. Образ можна зберігати в registry. А Compose може описувати середовище, в якому з цих образів запускаються потрібні контейнери. Ось і все. Для першого рівня цієї схеми цього більш ніж достатньо.
Тут корисно помітити ще один ефект. Щойно ви починаєте думати такими сутностями, розмова перестає бути містичною. Замість «ми якось запускаємо Docker» у вас з’являються нормальні формулювання: «ми зібрали image», «ми запустили container», «ми завантажуємо образ із registry», «ми описали стек через Compose». Це звучить сухіше, зате з інженерного погляду — набагато сильніше.
7. Чому курс саме такий
Цей словник не випадково з’являється саме зараз. Наступні теми курсу постійно спиратимуться на нього. Коли ми дістанемося до Dockerfile, мова піде про image. Коли почнемо дивитися на життєвий цикл, логи та базову діагностику, мова піде про container. Коли дійдемо до локального стека app + db, а згодом до app + db + cache + broker, у центрі опиниться Compose. А коли з’явиться розмова про доставлення артефактів між середовищами, без registry також нікуди.
Для Java/Spring-розробника тут є ще один важливий бонус. Така карта допомагає не тягнути в контейнерну тему старі, але незручні звички мислення. Наприклад, не сприймати Compose як «ще один вид image», не вважати registry місцем, «де застосунок працює», і не плутати артефакт із процесом.
Сильний технічний курс викликає довіру не пафосом, а доброю картою місцевості. У цьому сенсі сьогоднішній словник і є картою. Він компактний, але охоплює всю решту програми. І це помітно знижує тривогу: виявляється, Docker можна пояснювати не через магію, а через цілком звичайні інженерні сутності.
8. Типові помилки
Помилка №1: казати «образ працює».
Працює не образ, а контейнер, який створено з образу. Образ можна зібрати, зберігати, передавати, завантажити, повторно використовувати. Але сама поведінка сервісу починається вже в середовищі виконання, тобто всередині контейнера.
Помилка №2: плутати registry з місцем запуску.
Registry не відповідає за життя застосунку. Він не про логи, не про HTTP-порт і не про готовність. Це просто сховище артефактів. Якщо в голові змішати зберігання та запуск, далі плутається вже все.
Помилка №3: сприймати Compose як «різновид образу».
Compose описує середовище. Це інший рівень моделі. Він може посилатися на image, але сам image не замінює і не дублює. Те саме потім буде важливо і для локального стека app + db.
Помилка №4: жити одним спільним словом «Docker».
Щойно всі проблеми називаються однаково, ви втрачаєте діагностичний сигнал. Точна термінологія тут — не академізм, а спосіб швидше зрозуміти, що саме сталося і на якому рівні варто шукати причину.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ