Вопрос или проблема
Я использую образ tomsik68/xampp docker на моем Linux сервере.
Когда я перезагружаю сервер или удаляю контейнер (через docker rm myXampp), все изменения в базе данных теряются. Как сохранить изменения в базе данных на сервере?
Расположение базы данных в образе docker:
"/opt/lampp/var/mysql"
Я запускал контейнер с этим кодом:
docker run --name myXampp -p 3999:22 -p 4000:80 -d -v ~/myWebPages:/opt/lampp/htdocs tomsik68/xampp
Я хочу, чтобы все изменения в базе данных сохранялись на сервере. Спасибо, ребята!
Предполагая, что под “сохранением на сервер” вы подразумеваете сохранение содержимого вашей базы данных между последующими запусками контейнера, вам нужно создать Docker volume, в котором будут храниться ваши данные.
Так же, как вы монтируете ваши веб-страницы в директорию htdocs
, вы можете:
- выбрать любую директорию для базы данных на вашем локальном компьютере, или
- позволить Docker создать именованный volume для вас (например,
xamppdb
).
Например:
docker run --name myXampp \
-p 3999:22 -p 4000:80 -d \
-v ~/myWebPages:/opt/lampp/htdocs \
-v xamppdb:/opt/lampp/var/mysql \
tomsik68/xampp
Это предполагает, что содержимое /opt/lampp/var/mysql
должно сохраняться.
Как @slhck сказал, монтирование volume – это правильный способ сохранить данные базы данных.
Однако, приведенный пример ломает MySQL † потому что /opt/lampp/var/mysql
содержит сокет, который перестает работать, если он смонтирован в volume (по крайней мере, так я предполагаю).
Следуя примеру, данному в README, это работает, если монтировать только папку конкретной базы данных, например, /opt/lampp/var/mysql/mydb
для базы данных mydb
:
docker run --name myXampp \
-p 41061:22 -p 41062:80 \
-d \
-v ~/myProject:/www \
-v ~/myProject/mysql/mydb:/opt/lampp/var/mysql/mydb \
tomsik68/xampp:8
† Вот ошибка, которую я получил от mysql cli внутри контейнера:
$ docker exec -ti tavalade bash
root@0f5ef9b90cd2:/# /opt/lampp/bin/mysql -u root
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/opt/lampp/var/mysql/mysql.sock' (111)
и ошибка, которую я получил от phpmyadmin:
mysqli::real_connect(): (HY000/2002): Connection refused
Ответ или решение
Чтобы сохранить изменения в базе данных Docker при перезагрузке сервера или удалении контейнера, следует воспользоваться концепцией постоянного хранения данных с помощью Docker volumes. Это позволит вам сохранять данные базы данных на вашем сервере, сохраняя их в заданном местоположении, даже если контейнеры будут перезапущены. Рассмотрим подробнее, как это работает и как правильно настроить ваш процесс.
Теория
Когда вы работаете с базами данных в контейнерах Docker, по умолчанию все изменения, сделанные в базе данных, сохранены только в пределах жизненного цикла контейнера. Это означает, что при удалении или перезапуске контейнера все данные базы данных будут потеряны. Чтобы предотвратить это и обеспечить постоянное хранение данных, используем концепцию монтирования томов (volumes) или привязываем файлы (bind mounts) в Docker.
Docker volumes создаются и управляются непосредственно Docker, что делает их абстрагированием уровня хранения данных. Монтирование с использованием файлов/каталогов по-прежнему остается жизнеспособным решением, особенно если вы хотите контролировать местоположение хранения данных на сервере. Преимуществом томов является их переносимость и управление через Docker Engine, что упрощает их массовое использование и управление.
Пример
Ваша текущая команда запуска контейнера выглядит следующим образом:
docker run --name myXampp -p 3999:22 -p 4000:80 -d -v ~/myWebPages:/opt/lampp/htdocs tomsik68/xampp
Чтобы ваши данные базы данных сохранялись при рестарте контейнера, необходимо использовать монтирование томов. В частности, вам следует убедиться, что данные из директории /opt/lampp/var/mysql
, где находятся базы данных, будут монтироваться на постоянный том или в локальный каталог на сервере.
Однако, как отмечено в описании проблемы, прямое монтирование всей директории /opt/lampp/var/mysql
может привести к проблемам из-за монтирования сокета MySQL. Это означает, что эффективнее будет монтировать данные для конкретных баз данных вместо всей директории. Пример корректного монтирования тома для конкретной базы данных выглядит следующим образом:
docker run --name myXampp \
-p 3999:22 -p 4000:80 -d \
-v ~/myWebPages:/opt/lampp/htdocs \
-v ~/myDatabaseStorage/mydb:/opt/lampp/var/mysql/mydb \
tomsik68/xampp
Здесь ~/myDatabaseStorage/mydb
— это локальная директория на вашем сервере, в которую будут сохраняться данные базы данных mydb
.
Применение
-
Создайте каталог для хранения данных. Убедитесь, что у Docker есть доступ к каталогу, используемому для монтирования ваших данных. Вы можете создать каталог следующим образом:
mkdir -p ~/myDatabaseStorage/mydb
-
Запустите контейнер с обновленным монтированием. Скорректируйте вашу команду запуска, включив монтирование специфичного к вашей базе данных каталога, чтобы избежать проблем с MySQL socket:
docker run --name myXampp \ -p 3999:22 -p 4000:80 -d \ -v ~/myWebPages:/opt/lampp/htdocs \ -v ~/myDatabaseStorage/mydb:/opt/lampp/var/mysql/mydb \ tomsik68/xampp
-
Проверьте доступность данных. После завершения работы с контейнером и его остановки или удаления, вам стоит проверить, что данные все еще существуют в ранее указанном каталоге
~/myDatabaseStorage/mydb
. Это можно сделать, запустив новый контейнер или проверив содержимое через файловую систему. -
Автоматизация и управление. Для более продвинутого управления, вы можете рассмотреть использование Docker Compose, который позволяет описывать вашу конфигурацию контейнеров в более поддерживаемом и явном формате. Этот инструмент позволяет легко управлять зависимостями и параметрами запуска контейнеров, включая конфигурацию томов.
Используя эти шаги, вы сможете добиться сохранения всех изменений в ваших базах данных при работе с Docker контейнерами, предотвращая потерю данных и упрощая управление вашим приложением.