Пошук уроків, статей та іншого контенту
Розберете, як Compose спрощує запуск багатоконтейнерних застосунків і керування ними через декларативну конфігурацію.
Окремий контейнер зручно запускати командою:
docker run nginxАле реальний застосунок часто складається з кількох частин:
вебзастосунку;
бази даних;
кешу;
черги повідомлень;
допоміжних сервісів.
Якщо запускати кожен контейнер окремою довгою командою docker run, потрібно вручну пам’ятати:
які образи використовувати;
які змінні середовища передати;
які томи підключити;
як називаються контейнери;
у якій мережі вони мають працювати.
Docker Compose вирішує цю проблему. Він дає змогу описати всі сервіси застосунку в одному конфігураційному файлі, а потім запустити їх однією командою.
Docker Compose — інструмент для визначення та запуску багатоконтейнерних застосунків.
Конфігурація Compose зазвичай зберігається у файлі:
compose.yamlТакож можуть використовуватися назви compose.yml, docker-compose.yaml або docker-compose.yml.
У цьому файлі декларативно описують:
які сервіси потрібні застосунку;
з яких образів їх створювати;
які порти публікувати;
які змінні середовища використовувати;
які томи підключати;
які залежності існують між сервісами.
Декларативний підхід означає, що ми описуємо бажаний результат, а не покрокову послідовність команд.
Замість кількох команд:
docker network create app-network
docker run -d --name database --network app-network postgres:16
docker run -d --name adminer --network app-network -p 8080:8080 adminerможна описати потрібну інфраструктуру у compose.yaml і запустити її командою:
docker compose upРозглянемо приклад застосунку з двох контейнерів:
db — база даних PostgreSQL;
adminer — вебінтерфейс для роботи з базою даних.
Створіть порожню директорію та файл compose.yaml у ній:
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: app
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
volumes:
- db-data:/var/lib/postgresql/data
adminer:
image: adminer:4
ports:
- "8080:8080"
environment:
ADMINER_DEFAULT_SERVER: db
depends_on:
- db
volumes:
db-data:servicesУсі контейнери застосунку описують у секції services:
services:
db:
...
adminer:
...db та adminer — логічні імена сервісів. Compose використовує їх для керування контейнерами та внутрішньої взаємодії між ними.
Ім’я сервісу також може використовуватися як ім’я хоста в мережі Compose. Тому adminer може звертатися до бази даних за адресою db.
imageВластивість image визначає Docker-образ, з якого буде створено контейнер:
image: postgres:16-alpineУ прикладі використовуються готові образи з Docker Hub:
postgres:16-alpine — PostgreSQL на основі Alpine Linux;
adminer:4 — вебінтерфейс Adminer.
Compose завантажить образи автоматично, якщо їх ще немає на комп’ютері.
portsВластивість ports публікує порт контейнера на комп’ютері:
ports:
- "8080:8080"Формат такий:
порт_комп'ютера:порт_контейнераУ цьому прикладі:
Adminer слухає порт 8080 усередині контейнера;
цей самий порт доступний на комп’ютері;
до сервісу можна звернутися за адресою http://localhost:8080.
Публікувати порт бази даних не обов’язково. Інші сервіси Compose можуть звертатися до неї через внутрішню мережу.
environmentЗмінні середовища передаються сервісу через environment:
environment:
POSTGRES_DB: app
POSTGRES_USER: app
POSTGRES_PASSWORD: secretОбраз PostgreSQL використовує ці змінні під час першої ініціалізації бази даних.
volumesТом дає змогу зберігати дані незалежно від життєвого циклу контейнера:
volumes:
- db-data:/var/lib/postgresql/datadb-data — ім’я тому Docker, а /var/lib/postgresql/data — шлях усередині контейнера, де PostgreSQL зберігає дані.
Окремо том оголошений наприкінці файлу:
volumes:
db-data:Без тому дані бази можуть бути втрачені після видалення контейнера.
depends_ondepends_on:
- dbЦе вказує Compose, що контейнер adminer залежить від сервісу db.
Compose спочатку запустить db, а потім adminer. Водночас depends_on контролює порядок запуску контейнерів, але не гарантує, що база вже повністю готова приймати підключення.
Перейдіть у директорію з файлом compose.yaml і виконайте:
docker compose upCompose:
прочитає файл конфігурації;
завантажить відсутні образи;
створить мережу для застосунку;
створить том db-data;
створить і запустить контейнери;
покаже журнали їхньої роботи.
Після запуску відкрийте в браузері:
http://localhost:8080На сторінці Adminer для підключення до PostgreSQL введіть:
Сервер: db
Користувач: app
Пароль: secret
База даних: app
Значення db потрібно використовувати замість localhost, тому що Adminer працює в окремому контейнері, а PostgreSQL має ім’я сервісу db у внутрішній мережі Compose.
За замовчуванням docker compose up прив’язує термінал до журналів контейнерів. Щоб запустити сервіси у фоновому режимі, використовуйте прапорець -d:
docker compose up -dТепер термінал одразу буде доступний для інших команд.
Перевірити стан сервісів можна так:
docker compose psПриклад результату може містити два запущені сервіси:
NAME IMAGE STATUS PORTS
project-db-1 postgres:16-alpine Up 5432/tcp
project-adminer-1 adminer:4 Up 0.0.0.0:8080->8080/tcpТочні імена контейнерів залежать від назви директорії проєкту.
Щоб переглянути журнали всіх сервісів:
docker compose logsЩоб стежити за новими повідомленнями в реальному часі:
docker compose logs -fЖурнали лише одного сервісу:
docker compose logs -f dbПрапорець -f означає, що команда продовжить працювати та показувати нові повідомлення.
Щоб зупинити контейнери:
docker compose stopКонтейнери буде зупинено, але їхні дані та конфігурація залишаться.
Щоб зупинити й видалити контейнери та мережу:
docker compose downІменований том db-data зазвичай не видаляється командою down, тому дані PostgreSQL залишаться.
Щоб разом із контейнерами видалити й томи:
docker compose down -vЦю команду потрібно використовувати обережно: вона видалить збережені дані бази в томах, описаних у Compose-файлі.
Перезапустити всі сервіси:
docker compose restartПерезапустити лише базу даних:
docker compose restart dbЯкщо конфігурація змінилася, застосуйте її командою:
docker compose up -dCompose порівняє поточний стан із конфігурацією та за потреби пересоздасть контейнери.
Якщо образ потрібно завантажити заново:
docker compose pull
docker compose up -dКоманда docker compose exec дає змогу виконати команду в запущеному сервісі.
Наприклад, відкрити оболонку PostgreSQL:
docker compose exec db psql -U app -d appПісля запуску можна виконати SQL-команду:
SELECT current_database();Вийти з PostgreSQL можна командою:
\qНазва db у цій команді — це ім’я сервісу з compose.yaml, а не випадково згенероване ім’я контейнера.
Перед запуском можна перевірити, чи правильно Compose прочитав YAML-файл:
docker compose configЦя команда корисна, якщо:
у файлі є помилка відступів;
неправильно вказано назву властивості;
потрібно побачити підсумкову конфігурацію;
конфігурація використовує змінні середовища.
YAML чутливий до відступів. Для вкладених властивостей зазвичай використовують два пробіли.
Dockerfile і compose.yaml вирішують різні завдання.
Dockerfile описує, як створити один власний образ:
який базовий образ використати;
які файли скопіювати;
які залежності встановити;
яку команду запускати.
Compose-файл описує, як запустити один або кілька сервісів:
які образи використовувати;
як з’єднати контейнери;
які порти опублікувати;
які томи та змінні середовища підключити.
Compose може використовувати як готові образи через image, так і створювати образ із Dockerfile через build. У цьому уроці використано готові образи, тому окремий Dockerfile не потрібен.
Для проєкту з compose.yaml типовий цикл виглядає так:
# Запустити сервіси у фоновому режимі
docker compose up -d
# Перевірити стан контейнерів
docker compose ps
# Переглянути журнали
docker compose logs -f
# Зупинити та видалити контейнери
docker compose downCompose зберігає опис інфраструктури у файлі, який можна додати до репозиторію разом із кодом проєкту. Завдяки цьому іншим розробникам не потрібно вручну відтворювати довгі команди запуску.
localhost для іншого сервісуУсередині контейнера localhost означає поточний контейнер, а не комп’ютер і не інший сервіс.
Неправильно для підключення Adminer до PostgreSQL:
localhostПравильно:
dbdb — ім’я сервісу в Compose-файлі.
Запис:
ports:
- "8080:8080"означає:
порт комп’ютера:порт контейнераЯкщо вказати "80:8080", сервіс буде доступний на порту 80 комп’ютера, хоча всередині контейнера він і далі слухатиме 8080.
Команда:
docker compose down -vвидаляє томи. Для бази даних це може означати втрату всіх збережених даних.
Compose шукає compose.yaml у поточній директорії. Якщо команда не знаходить файл, перевірте поточний шлях:
pwdАбо явно передайте шлях до файлу:
docker compose -f path/to/compose.yaml up -ddepends_on визначає порядок запуску, але сервіс може ще ініціалізуватися після старту контейнера. Тому застосунок, який підключається до бази даних, має бути готовим повторити підключення, якщо база ще не приймає запити.
Docker Compose спрощує роботу із застосунками, що складаються з кількох контейнерів.
У compose.yaml декларативно описують сервіси, образи, порти, змінні середовища, томи та залежності.
Команда docker compose up створює й запускає описані сервіси.
Прапорець -d запускає їх у фоновому режимі.
docker compose ps показує стан сервісів, а docker compose logs — їхні журнали.
docker compose down зупиняє та видаляє контейнери, але томи зазвичай залишаються.
Імена сервісів Compose використовуються як адреси для взаємодії контейнерів у внутрішній мережі.