Docker Compose
Docker Compose — це технологія, яка дозволяє локально запускати багатоконтейнерні додатки, тобто одночасно один або більше контейнерів. Створення Docker Compose є типовою задачею для DevOps-інженера.
docker-compose — це плагін до Docker, а також це файл з конкретно визначеною нотацією. Колись цей плагін був окремим додатком, але компанія Docker купила його та інтегрувала з рештою системи. docker-compose дозволяє визначати контейнери, які треба запустити, залежності між ними, мережі тощо.
docker-compose можна вважати твоїм першим оркестратором контейнерів. Оркестратор — це додаткове програмне забезпечення, яке допомагає керувати контейнерами, коли їх стає багато, або налаштувати якусь нетипову поведінку.
Структура docker-compose
docker-compose — це YML-файл. Нотація такого файлу досить проста і дещо схожа на JSON, але без дужок, наприклад:
docker-compose.yml
У цьому файлі спочатку пишемо поле, потім двокрапку, потім значення поля. У прикладі можна побачити такі поля:
version— це версія плагінуdocker-compose;networks— це необовʼязкове поле, що описує Docker-мережі;services— це опис та конфігурація того, який контейнер треба запустити і які конфігурації задати;volumes— це volumes, які можна під'єднати у секціїservices.
Додамо мережу
Тепер зробимо так, щоб з docker-compose створювалась Docker-мережа, яку будуть використовувати контейнери:
Під секцією networks додай табуляцію і напиши назву мережі. Обов'язково постав двокрапку, щоб не порушити синтаксис. Нижче напиши тип драйвера мережі.
💡 bridge — це тип мережі, яку Docker використовує за замовчуванням. Контейнери, які підключені до мережі такого типу, отримають IP-адресу, виділену з загального IP-пулу цієї мережі. Контейнери, які підключені до одної bridge-мережі, можуть комунікувати між собою, використовуючи внутрішню IP-адресу або назву контейнера.
💡 Ми зазделегідь можемо не знати яку конкретно ІР отримає контейнер тому треба взаємодію додатків з різних контейнерів організовувати по доменним іменам (імʼя контейнеру буде доменним іменем)
Додамо volume
Для початку визначимо наш volume у відповідній секції:
У volumes є різні типи драйверів, ми будемо використовувати тип драйвера за замовчуванням — local, який дозволяє створювати volumes на машині хоста контейнера. Щоб використати тип драйвера за замовчуванням, не потрібно вказувати нічого додатково.
Додамо базу даних
Додамо базу даних до services:
mysql:
image: my-sql:1.2
build:
context: .
dockerfile: Dockerfile.mysql
container_name: my-sql
ports:
- "3306:3306"
volumes:
- db-data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=1234
- MYSQL_DATABASE=app_db
- MYSQL_USER=app_user
- MYSQL_PASSWORD=1234
networks:
- db-data-net
Тут:
- my-sql:1.2 — це назва Image, який треба завантажити з Docker Hub або знайти локально.
- build — це інструкції, які виконаються, якщо Image не знаходиться локально. Іншими словами, ми описуємо команду, задаємо контекст і шлях до файлу Dockerfile відносно docker-compose.
- volumes - вказуємо драйвер та шлях куди мотувати в системі
- ports - маппінг портів
- environment - визначаємо змінні середовища.
- networks - задаємо яку мережу використовуватимемо з загального розділу networks
Додамо Python-додаток
Для нашого додатка задамо:
- Image, а якщо його немає, тоді
build-параметри. - Мепінги портів.
- Змінну середовища, яку ми визначили ще в
Dockerfileдля Python-додатку. - Мережу.
- Параметр
depends_on, який вказує, щоdocker-composeспочатку ініціює запуск бази даних, але не очікуватиме на її повне завершення запуску, тому ще додамо політикуrestart.
pythonapp:
image: app:1.2
build:
context: .
dockerfile: Dockerfile.app
ports:
- "8080:8080"
environment:
- APP_ENV=Development
networks:
- db-data-net
depends_on:
- mysql
restart: unless-stopped
Також модифікуємо connection string у додатку:
У нас тут прописана IP контейнера, але це не дуже зручно з двох причин: 1. IP може змінитись. 2. Ми запускаємо два контейнери одразу. Ми використаємо назву контейнера для бази даних:Час це все запустити, але спочатку очистимо увесь кеш:
У терміналі у теці з docker-compose і виконай наступну команду:
Параметр -d еквівалентний --detach і означає, що вивід логів буде прихований. Якщо не вказувати цей параметр, то логи обох контейнерів ми побачимо в консолі.
Cтатус контейнерів:
Логи контейнерів: Щоб зупинити всі контейнери: Можна перезапускати в одному рядку: