6.23 Docker Compose в дії: приклад налаштування MySQL

TheHost Docker Compose Banner

Docker Compose – це інструмент для визначення та запуску багатоконтейнерних Docker-додатків. За його допомогою ви описуєте конфігурацію сервісів (контейнерів) в одному YAML-файлі, а потім однією командою можете запустити відразу кілька контейнерів, налаштованих для спільної роботи. Простіше кажучи, Docker Compose дозволяє одним дією підняти весь стек сервісів вашого додатку (наприклад, веб-сервер + база даних) замість ручного запуску кожного контейнера окремо. Це особливо корисно, коли додаток складається з кількох взаємопов’язаних частин – наприклад, веб-сайту і бази даних, яка йому потрібна.

У цьому посібнику ми розглянемо використання Docker Compose на прикладі розгортання MySQL. Ми покажемо, як створити файл налаштування docker-compose.yml з MySQL, організувати постійне зберігання даних через томи (volumes) і налаштувати мережу (network) для зв’язку між контейнерами. Також ви дізнаєтесь, як запустити і перевірити роботу контейнера MySQL, як підключитися до бази даних як з хоста, так і з іншого контейнера (наприклад, з phpMyAdmin), а в кінці – основні рекомендації щодо безпеки та управління паролями (з використанням файлу .env).

Вимоги:

  • Замовлена послуга віртуального або виділеного сервера.
  • На сервері має бути встановлений Docker. Якщо він не встановлений, можете встановити згідно нашої інструкції Docker.
  • Переконайтеся, що у вас є sudo-доступ або ваш користувач має права запускати Docker (наприклад, входить до групи docker на Linux).

Налаштування docker-compose.yml для MySQL

Почнемо з підготовки файлу docker-compose.yml, в якому опишемо сервіс бази даних MySQL (і додатково – phpMyAdmin для зручності управління). Нижче наведено приклад вмісту файлу з коментарями щодо основних налаштувань:

version: '3.8'  # Версія формату Compose-файлу

services:
  db:
    image: mysql:8.0           # Офіційний образ MySQL 8.0
    container_name: mysql-db   # Ім'я контейнера (необов'язково, для зручності)
    ports:
      # Зверніть увагу, що якщо у вас вже є встановлений MYSQL, то щоб уникнути конфлікту, необхідно вибрати інший порт, наприклад "3307:3307"
      - "3306:3306"            # Проброс порту MySQL на хост (для підключення ззовні). 
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}   # Пароль root (береться з .env)
      MYSQL_DATABASE: ${MYSQL_DATABASE}             # Ім'я БД для створення (з .env)
      MYSQL_USER: ${MYSQL_USER}                     # Додатковий користувач БД (з .env)
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}             # Пароль дод. користувача (з .env)
    volumes:
      - db_data:/var/lib/mysql    # Іменований том для зберігання даних БД
    networks:
      - app-network              # Підключення до користувацької мережі

  phpmyadmin:
    image: phpmyadmin:latest    # Образ phpMyAdmin
    container_name: myadmin     # Ім'я контейнера phpMyAdmin
    depends_on:
      - db                      # Спочатку має стартувати контейнер db
    ports:
      - "8080:80"               # phpMyAdmin буде доступний на порту 8080
    environment:
      PMA_HOST: db              # Хост БД для підключення (ім'я сервісу MySQL)
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}  # Пароль root для доступу
    networks:
      - app-network

# Визначаємо іменований том і мережу
volumes:
  db_data:                      # Том для даних MySQL (Docker сам зберігає його дані)
networks:
  app-network:                  # Користувацька мережа для наших сервісів
    driver: bridge

У цьому Compose-файлі визначено два сервіси:

  • db - контейнер з MySQL. Йому задані змінні оточення MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD (паролі та імена будуть задані через зовнішній файл .env, про який нижче). Також для нього змонтовано том db_data в директорію /var/lib/mysql всередині контейнера – це шлях, де MySQL зберігає дані. Завдяки тому, що ми вказали іменований том, дані бази зберігатимуться між перезапусками контейнера (навіть якщо контейнер видалити, том залишиться, поки ви його явно не видалите). Порт 3306 проброшено на хост, щоб при необхідності можна було підключатися до MySQL ззовні (наприклад, з локального хоста або віддалено).
  • phpmyadmin - контейнер з phpMyAdmin, веб-інтерфейсом для управління MySQL. Ми додали його для прикладу, щоб продемонструвати підключення до бази з іншого контейнера. Цей контейнер залежить від db (через depends_on, що забезпечує запуск MySQL першим), і в змінних середовища вказано, куди йому підключатися: PMA_HOST: db означає, що phpMyAdmin буде шукати сервіс MySQL за хостнеймом db. У Docker Compose за замовчуванням створюється спільна мережа для всіх сервісів додатку, і вони можуть звертатися один до одного за іменами сервісів. Ми явно вказали мережу app-network для наочності – обидва контейнери в ній перебувають, тому phpMyAdmin може підключитися до MySQL за ім’ям db. Порт phpMyAdmin 80 ми пробросили на 8080 на хосту – відкривши браузер за адресою http://<ваш сервер>:8080/ ви потрапите в інтерфейс phpMyAdmin.

Налаштування змінних оточення в .env-файлі

Файл .env: Зверніть увагу, в docker-compose.yml використовуються конструкції ${…} – це посилання на змінні оточення. Значення цих змінних ми задамо в окремому файлі .env (в тій самій директорії, де і docker-compose.yml). Docker Compose автоматично підхоплює змінні з файлу .env, розташованого в каталозі проекту. Використання окремого .env-файлу спрощує управління налаштуваннями і дозволяє не дублювати паролі та інші секрети в різних місцях конфігурації.

Створіть поруч з docker-compose.yml файл .env і додайте туди наступні рядки (підставте свої значення замість прикладів):

MYSQL_ROOT_PASSWORD=StrongRootPass123   # обов'язковий пароль для користувача root MySQL
MYSQL_DATABASE=myappdb                  # ім'я бази даних, яку потрібно створити при старті
MYSQL_USER=myuser                       # ім'я додаткового користувача
MYSQL_PASSWORD=UserPass456              # пароль для додаткового користувача
  • MYSQL_ROOT_PASSWORD обов’язкова змінна, без неї контейнер MySQL не запуститься. Згідно з документацією, вона задає пароль суперкористувача “root” для MySQL. Використовуйте достатньо складний пароль.
  • MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD – ці змінні необов’язкові. Якщо вказати, то при першому запуску контейнера буде автоматично створено нову базу даних з заданим ім’ям, а також користувача з ім’ям MYSQL_USER і з паролем MYSQL_PASSWORD, якому надано права на цю базу. Це зручно, наприклад, щоб відразу підготувати окремого адміністратора для додатку. (Якщо вам не потрібні додатковий користувач і база, можете опустити ці змінні).

Після підготовки docker-compose.yml і .env ми готові запускати наші сервіси. Далі розглянуті кроки запуску та перевірки роботи – вони практично однакові для різних дистрибутивів Linux, проте ми наведемо окремі примітки для Debian/Ubuntu та для CentOS/AlmaLinux/RockyLinux.

Запуск та перевірка

  1. Запустіть Docker Compose: перебуваючи в директорії з файлом docker-compose.yml, виконайте команду запуску compose
docker compose up -d
  • -d запустить контейнери у фоновому режимі (демонізовано). Після виконання команди compose збере і запустить вказані у файлі сервіси. Ви побачите вивід, що контейнери створені та запущені. Наприклад:

Docker Compose автоматично створив мережу app-network і том db_data для нашого проекту (якщо вони не були створені раніше). За замовчуванням, якщо не вказано інакше, Compose формує ім’я мережі за ім’ям проекту (зазвичай збігається з ім’ям папки) з суфіксом. У нашому випадку ми явно задали ім’я мережі, тому вона так і називається. Всі контейнери проекту підключені до цієї мережі і можуть спілкуватися один з одним за сервісними іменами.

  1. Перевірте, що контейнери запущені: виконайте команду списку контейнерів
docker-compose ps

або аналогічно docker ps, вона покаже взагалі всі запущені контейнери Docker

docker ps

У виводі мають відображатися як мінімум два контейнери – MySQL і phpMyAdmin – зі статусом “Up”. Наприклад:

  1. Перегляньте логи MySQL: при першому запуску корисно переконатися, що база даних ініціалізована
команда перегляду логів
docker-compose logs -f db

Вона покаже журнали контейнера db (наш MySQL). Ви повинні побачити повідомлення про те, що сервер MySQL запущений і слухає порт 3306, а також, можливо, що створено базу даних myappdb і користувача myuser (якщо ви їх задавали). Після рядка “[Server] /usr/sbin/mysqld: ready for connections.” можна вважати, що БД готова до роботи.

  1. Підключення до бази даних з хост-системи

Тепер спробуємо підключитися до MySQL, що працює всередині контейнера, наприклад з командного рядка сервера. Для цього на хості має бути встановлений MySQL-клієнт. У Debian/Ubuntu можна встановити пакет: sudo apt install mysql-client. Після цього підключаємося командою до локального порту сервера:

mysql -h 127.0.0.1 -P 3306 -u root -p

При виконанні вас попросять ввести пароль – введіть той, що ви вказали в змінній MYSQL_ROOT_PASSWORD у файлі .env. Якщо все зроблено правильно, ви потрапите в консоль MySQL на контейнері. Можна виконати запит SHOW DATABASES; щоб побачити список баз (там має бути myappdb і системні бази).

  1. Підключення до бази з іншого контейнера

У нашому прикладі вже запущений контейнер phpMyAdmin, який підключений до того ж проекту Compose. Відкрийте веб-браузер і перейдіть за адресою http://<адреса_сервера>:8080/. Ви повинні побачити інтерфейс phpMyAdmin. У полі Server вже підставлено db (оскільки ми вказали PMA_HOST: db), залишилося ввести Username = root і Password = ваш MYSQL_ROOT_PASSWORD (як варіант, можна увійти під користувачем myuser з паролем UserPass456 – тоді в полі сервер можна теж залишити db, це буде підключення до тієї ж БД). Якщо авторизація пройшла, ви отримаєте веб-доступ до вашої бази даних. Таким чином, phpMyAdmin, перебуваючи в одній мережі з MySQL, звернувся до нього за внутрішнім ім’ям хоста і успішно підключився.

  1. Зупинка контейнерів

Після роботи ви можете зупинити і видалити запущені контейнери командою:

docker-compose down

Ця команда зупинить сервіси і від’єднає томи, але не видалить іменований том з даними db_data (для видалення томів потрібно додати прапорець -v). Це означає, що при наступному запуску up дані в базі збережуться. Якщо ж ви хочете повністю скинути середовище (видалити контейнери, мережу і том з даними), використовуйте:

docker-compose down -v