Мы уже разобрались с тем, что такое Docker и его основными понятиями – контейнер и образ. А так же выполнили несколько практических примеров.
Однако, когда мы говорим не о примерах, а о реальной работе с Docker важным вопросом становится сохранение данных — как сохранить их так, чтобы они не потерялись при остановке или удалении контейнера. В этом помогает монтирование томов.
В этой статье мы разберемся с тем, что такое тома в Docker, зачем они нужны, и как правильно монтировать тома, чтобы сохранять данные контейнера.
Что такое тома в Docker?
Тома (volumes) — это специальные области памяти, которые используются для хранения данных вне жизненного цикла контейнера.
Когда вы создаёте том, он существует независимо от контейнера. Это означает, что даже если вы удалите контейнер, данные в томе останутся, и можно использовать их снова.
Зачем нужны тома?
- Чтобы сохранять важные данные (например, базу данных, файлы, логи)
- Для обмена файлами между контейнерами
- Чтобы избежать потери данных при удалении или перезапуске контейнера
- Для повышения безопасности и управления данными
Как создать и подключить том в Docker
- 1. Создание тома
- 2. Монтирование тома при запуске контейнера
- 3. Использование директории на хосте как тома
Для работы с томами и их монтирования используются следующие шаги:
1. Создание тома
Самый простой способ — использовать команду volume create:
[root@waky ~]# docker volume create my_volume
my_volume
[root@waky ~]# docker volume ls
DRIVER VOLUME NAME
local my_volume
[root@waky ~]#
Мы создали новый том с именем my_volume, команда volume ls выводит список томов.
Созданный таким образом том хранится по пути /var/lib/docker/volumes/.
2. Монтирование тома при запуске контейнера
Чтобы наглядно увидеть разницу между использованием томов и их отсутствием создадим два контейнера, с монтирование и без соответственно.
[root@waky ~]# docker run -d --name container_without_volume -p 8080:80 nginx
a38ffe17c0227396617ac66593da3481ae733bf271ef9710826f05e9d1e39574
[root@waky ~]# docker run -d --name container_with_volume -p 8081:80 -v my_volume:/usr/share/nginx/html nginx
94c24c9d4edcf96bde53ead712e0fcc94c6b1bde694427862b0bbb41d89be7b4
[root@waky ~]#
Первый контейнер container_without_volume не имеет тома и привязан к порту (–p) 8080 сервера.
У второго контейнера, связанного с портом 8081, том my_volume монтируется (-v) в контейнер по пути /usr/share/nginx/html nginx
На данном этапе веб сервер NGINX каждого контейнера возвращает дефолтную страницу приветствия:
[root@waky ~]# curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
…
</body>
</html>
[root@waky ~]# curl localhost:8081
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
…
</body>
</html>
[root@waky ~]#
Код данной страницы хранится в контейнере в файле /usr/share/nginx/html/index.html
Давайте перезапишем данный файл, в рамках данного примера мы не будем заморачиваться с html разметкой:
[root@waky ~]# docker exec -it container_without_volume sh -c "echo 'Welcome from NO VOLUME container' > /usr/share/nginx/html/index.html"
[root@waky ~]# docker exec -it container_with_volume sh -c "echo 'Welcome from WITH VOLUME container' > /usr/share/nginx/html/index.html"
[root@waky ~]#
С помощью команды exec -it можно подключиться к консоли (sh) контейнера напрямую. Либо отправить на выполнение команду (-c).
Чтобы не заходить в консоль каждого контейнера, мы использовали второй способ, передав командуecho 'TEXT' > /usr/share/nginx/html/index.html
Еще раз проверим ответ веб серверов:
[root@waky ~]# curl localhost:8080
Welcome from NO VOLUME container
[root@waky ~]# curl localhost:8081
Welcome from WITH VOLUME container
[root@waky ~]#
На данном этапе разница между контейнером с и без тома не видна. Удалим и пересоздадим контейнеры:
[root@waky ~]# docker stop container_without_volume container_with_volume
container_without_volume
container_with_volume
[root@waky ~]# docker rm container_without_volume container_with_volume
container_without_volume
container_with_volume
[root@waky ~]# docker run -d --name container_without_volume -p 8080:80 nginx
298eaffc502720fe8954ca9f53ba1b27884798871401a2c2ed1fb85ba8b2dbf8
[root@waky ~]# docker run -d --name container_with_volume -p 8081:80 -v my_volume:/usr/share/nginx/html nginx
44f2dd4934cf6183c4c379746f9a60dcdfe6d5ffab2e6edef9e55d4ea9cafac5
[root@waky ~]#
Снова проверим ответ:
[root@waky ~]# curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
…
</body>
</html>
[root@waky ~]# curl localhost:8081
Welcome from WITH VOLUME container
[root@waky ~]#
Первый контейнер (без тома) снова показывает дефолтную страницу NGINX, новый контейнер не знает ничего о прошлых изменениях.
Второй контейнер напротив, подгрузил измененные файлы из тома, которые там сохранились от прошлого такого же контейнера.
Сохраненные файлы лежат в соответствующей директории сервера:
[root@waky ~]# ls /var/lib/docker/volumes/my_volume/_data/
50x.html index.html
[root@waky ~]# cat /var/lib/docker/volumes/my_volume/_data/index.html
Welcome from WITH VOLUME container
[root@waky ~]#
Если мы изменим файлы непосредственно в этой директории, с помощью текстового редактора или другим образом, эти изменения отразятся на контейнере:
[root@waky ~]# echo "Use volumes to save data" >> /var/lib/docker/volumes/my_volume/_data/index.html
[root@waky ~]# curl localhost:8081
Welcome from WITH VOLUME container
Use volumes to save data
[root@waky ~]#
3. Использование директории на хосте как тома
Порой удобнее использовать папку на сервере вместо отдельного тома. Для этого нужно связать путь на сервере и путь внутри контейнера.
Создадим отдельную директорию и файл index.html внутри:
[root@waky ~]# mkdir -p /home/practice/html
[root@waky ~]# touch /home/practice/html/index.html
[root@waky ~]#
Используйте текстовый редактор, чтобы написать простую html страничку, например:
<!DOCTYPE html>
<html>
<head>
<title>Mount from directory</title>
</head>
<body>
<p>This page is mounted to the container from a directory.</p>
</body>
</html>
Создадим новый контейнер и проверим, подгрузилась ли к нему наша страничка:
[root@waky ~]# docker run -d --name container_from_dir -p 8082:80 -v /home/practice/html:/usr/share/nginx/html nginx
228f6c5288bf01103091ecaf3399a931a6ecc65b402816a55aec13b74b529e9c
[root@waky ~]# curl localhost:8082
<!DOCTYPE html>
<html>
<head>
<title>Mount from directory</title>
</head>
<body>
<p>This page is mounted to the container from a directory.</p>
</body>
</html>
[root@waky ~]#
Все сработало ожидаемо.
Заключение
Монтирование томов в Docker — это важный инструмент для сохранения данных контейнеров.
Оно обеспечивает надежность и удобство в управлении данными, позволяет сохранить важную информацию независимо от жизненного цикла контейнера.
Правильное использование томов — залог успешной работы с Docker и стабильности ваших приложений.