Использование MySQL в контейнере Docker - mcodex

Использование MySQL в контейнере Docker

1. Установка Docker

curl -fsSL https://get.docker.com | sh

# добавляем текущего пользователя в группу docker
sudo usermod -aG docker $USER
newgrp docker

2. Файл docker-compose.yaml

Создаем папку, например, /docker-containers/mysql, в ней файл docker-compose.yaml

services:
  mysql:
    image: mysql:8.0
    container_name: mysql_container
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: your_root_password
      MYSQL_DATABASE: my_project_db
      MYSQL_USER: my_project_user
      MYSQL_PASSWORD: my_project_password
    volumes:
      - mysql_data:/var/lib/mysql
      - ./conf.d:/etc/mysql/conf.d
    ports:
      - "127.0.0.1:3306:3306"

volumes:
  mysql_data:

Используем образ MySQL фиксированной версии, что бы в случае пересоздания контейнера не столкнуться с проблемами несовместимости, которые потенциально могут быть, если использовать образ latest.

Пароли и имена придумываем свои, пароли долджны быть сложные, MYSQL_ROOT_PASSWORD используется при инициализации контейнера, в дальнейшем он будет нужен для подключения к MySQL от имени пользователя root, остальные данные будут нужны при подключении проекта.

3. Запускаем контейнер

cd /docker-containers/mysql
docker compose up -d

# Проверяем, что контейнер запущен
docker ps
docker logs mysql_container

# включаем автозапуск docker после перезагрузки VPS
sudo systemctl enable docker

При первом запуске контейнера Docker-образ MySQL сам создаёт базу и пользователя, а так-же дает пользователю все права на эту базу.

4. Импорт дампа в контейнер

На данном шаге в нашем контейнере существует пустая база данных my_project_db, в которую можно, при необходимости, загружить дамп проекта. Для этого выполняем mysql внутри контейнера.

docker exec -i mysql_container mysql -u my_project_user -p'my_project_password' my_project_db < /path/to/dump/backup-dump.sql

Важно: это работает только при первом запуске, когда volume ещё пустой. Если контейнер уже запускался и данные есть — переменные игнорируются, база уже существует.

Проверям, что импорт прошел успешно.

docker exec -it mysql_container mysql -u my_project_user -p'my_project_password' my_project_db -e "SHOW TABLES;"

В выводе должен быть список таблиц в базе данных my_project_db

5. Подключаем проект

Теперь нужно подключить проект к контейнеру с базой данных. Проекты могут использовать разные фреймворки и CMS.

Вариант А. Проект на WordPress.

Переходим в папку проекта, открываем файл wp-config.php, меняем значения констант.

define( 'DB_NAME', 'my_project_db' );
define( 'DB_USER', 'my_project_user' );
define( 'DB_PASSWORD', 'my_project_password' );
define( 'DB_HOST', '127.0.0.1:3306' );

Проверяем, что сайт открывается, нет ошибки подключения в базе данных.
После подключение проекта к контейнеру, СУБД на хостинге больше не нужна, можно удалить.

6. Добавление еще одной базы данных

Сейчас в контейнере создана только одна база данных для проекта my_project. Предположим, на этом же VPS расположен еще один проект, my_project2. Создадим в этом же контейнере еще одну БД для этого проекта. Для этого заходим в контейнер как пользователь root (пароль берем из MYSQL_ROOT_PASSWORD файла docker-compose.yaml ) и создаем нового пользователя и базу данных.

# Зайди в контейнер
docker exec -it mysql_container mysql -u root -p

# Внутри MySQL создай всё для второго сайта
CREATE DATABASE my_project2_db;
CREATE USER 'my_project2_user'@'%' IDENTIFIED BY 'my_project2_password';
GRANT ALL PRIVILEGES ON my_project2_db.* TO 'my_project2_user'@'%';
QUIT;

Подключение во второй проект аналогично п5.

7. Хранение данных

Разбираемся, где лежат файлы MySQL на хост-машине.
В docker-compose.yaml указан именованный том mysql_data. По сути это папка на хосте, в которой лежат файлы MySQL. Так же указано, что на нее маппируется папка /var/lib/mysql в контейнере (стандартная папка с данными MySQL). Что бы узнать точное имя тома (папки) можно выполнить команду:

docker volume ls

# Вывод
# DRIVER    VOLUME NAME
# local     mysql-docker_mysql_data
# local     mysql_mysql_data

Видно, что точное имя тома mysql_mysql_data, так как к имени, указанному в опции volume добавляется имя папки, в которой лежит docker-compose.yaml, которое считается префиксом проекта.

Проверяем, где находится данный том

docker volume inspect mysql_mysql_data

# Вывод
# ....
# "Mountpoint": "/var/lib/docker/volumes/mysql_mysql_data/_data",
# "Name": "mysql_mysql_data",
# ....

Mountpoint — это и есть путь к папке тома на хост-машине.
Том не зависит от контейнера, поэтому при остановке, перезапуске, удалении контейнера данные в базе данных будут сохранены.

Сделать дамп одной базы данных

docker exec mysql_container mysqldump \
  -u my_project_user -p'my_project_password' \
  my_project_db > my_project_db.sql

Сделать дамп всех баз данных

docker exec mysql_container mysqldump \
  -u root -p'your_root_password' \
  --all-databases > backup_all.sql

Восстановление из дампа

docker exec -i mysql_container mysql \
  -u my_project_user -p'my_project_password' \
  my_project_db < backup.sql

8. Полезные команды docker

Напоминание:
1. mysql_container — это не зарезервированное слово, это имя контейнера, заданное в файле docker-compose.yaml (см. п2), может быть любым.
2. команда ‘docker’ может выполнятся из любой папки.
3. команда ‘docker compose’ выполняется из папки, в которой находится файл docker-compose.yaml (или указывается путь к файлу через флаг -f)

ДействиеКоманда
Запустить контейнер в режиме демонаdocker compose up -d
Посмотреть все запущенные контейнерыdocker ps
Остановить все запущенные контейнерыdocker stop $(docker ps -a -q)
Удалить все остановленные контейнерыdocker rm $(docker ps -a -q)
Остановить контейнер (данные сохраняются)docker compose stop
Остановить и удалить контейнер (данные сохраняются)docker compose down
Перезапустить контейнер (данные сохраняются)docker compose restart
Удалить контейнер mysql_container (данные сохраняются)docker rm mysql_container
Удалить контейнер вместе с данными docker compose down -v
Посмотреть логи контейнера mysql_containerdocker logs -f mysql_container
Войти в MySQL как root в контейнере mysql_container docker exec -it mysql_container mysql -u root -p
Сделать дампdocker exec mysql_container mysqldump -u root -p my_project_db > my_project_db.sql
Зайти в контейнер mysql_container docker exec -it mysql_container /bin/bash
Удаление всех контейнеров, образов, сетейdocker system prune
Удаление всех контейнеров, образов, сетей, томовdocker system prune —volumes