Урок 5 из 8 · 20 мин · обновлено
Данные: тома и монтирование папок
Почему данные внутри контейнера пропадают вместе с ним, как сохранить их в томе на примере PostgreSQL, как подключить папку с компьютера к контейнеру и как управлять томами.
Контейнер забывает
Контейнер — временная вещь. Всё, что программа записала внутри, живёт, пока жив контейнер. Удалили контейнер — данные пропали. Для веб-сервера со статической страницей это не страшно. Для базы данных — катастрофа.
Проверим на PostgreSQL. Запустим базу без тома:
docker run -d --name db -e POSTGRES_PASSWORD=secret postgres:16
-e передаёт в контейнер переменную окружения: образ postgres требует задать пароль администратора. Пароль secret годится только для учебного примера.
Создадим таблицу. Пока используем готовую команду — что она делает, разберём в уроке 8:
docker exec -it db psql -U postgres -c "CREATE TABLE notes (text TEXT); INSERT INTO notes VALUES ('Привет');"
Удалим контейнер и запустим новый — таблицы там не будет. Данные жили внутри старого контейнера и исчезли вместе с ним.
docker rm -f db
Флаг -f останавливает и удаляет контейнер одной командой.
Тома
Том — хранилище данных, которым управляет Docker. Он существует отдельно от контейнеров: удалили контейнер — том остался.
Запустим базу с томом:
docker run -d --name db -e POSTGRES_PASSWORD=secret -v pgdata:/var/lib/postgresql/data postgres:16
-v pgdata:/var/lib/postgresql/data — подключить том pgdata к папке, где PostgreSQL 16 хранит данные. Если тома ещё нет, Docker создаст его сам.
Повторим эксперимент: создадим таблицу, удалим контейнер и запустим новый с тем же томом:
docker exec -it db psql -U postgres -c "CREATE TABLE notes (text TEXT); INSERT INTO notes VALUES ('Привет');"
docker rm -f db
docker run -d --name db -e POSTGRES_PASSWORD=secret -v pgdata:/var/lib/postgresql/data postgres:16
docker exec -it db psql -U postgres -c "SELECT * FROM notes;"
text
--------
Привет
(1 row)
Таблица на месте: новый контейнер нашёл данные в томе.
Путь к данным зависит от программы и иногда — от версии. Его указывают в описании образа на Docker Hub. Это ещё одна причина фиксировать тег: у новых основных версий PostgreSQL путь к данным в официальном образе может отличаться.
Монтирование папки
Второй способ — подключить к контейнеру папку с вашего компьютера. Удобно, когда вы правите файлы и хотите сразу видеть результат. Вернёмся к сайту из прошлого урока: запустите nginx и подключите папку my-site туда, откуда он отдаёт страницы.
В терминале Linux, macOS или Git Bash:
docker run -d --name live -p 8080:80 -v "$(pwd)":/usr/share/nginx/html:ro nginx:alpine
В PowerShell на Windows вместо "$(pwd)" пишут "${PWD}".
:ro в конце — только для чтения: контейнер не сможет менять ваши файлы. Измените index.html в папке, обновите страницу — изменения видны сразу, без сборки образа. Когда закончите, удалите контейнер: docker rm -f live.
Когда что использовать:
- том — для данных программ: базы данных, загруженные файлы;
- монтирование папки — для файлов, которые вы правите сами: код и страницы при разработке.
Управление томами
docker volume ls # список томов
docker volume inspect pgdata # подробности: где лежит, когда создан
docker volume rm pgdata # удалить том
docker volume rm удаляет данные навсегда. Том, подключённый к существующему контейнеру, удалить не получится — сначала удалите контейнер.
Попробуйте сами. Запустите PostgreSQL с томом notes-data, создайте таблицу и запись, удалите контейнер, запустите новый с тем же томом и убедитесь, что запись на месте. В конце удалите и контейнер, и том.
Решение
docker run -d --name notes -e POSTGRES_PASSWORD=secret -v notes-data:/var/lib/postgresql/data postgres:16
docker exec -it notes psql -U postgres -c "CREATE TABLE notes (text TEXT); INSERT INTO notes VALUES ('Запись из урока 5');"
docker rm -f notes
docker run -d --name notes -e POSTGRES_PASSWORD=secret -v notes-data:/var/lib/postgresql/data postgres:16
docker exec -it notes psql -U postgres -c "SELECT * FROM notes;"
Если exec сразу после запуска ответил ошибкой подключения — подождите несколько секунд: базе нужно время, чтобы стартовать.
Уборка:
docker rm -f notes
docker volume rm notes-data
Мини-тест: проверьте себя
Закрепите урок: несколько вопросов, разбор ответов — в конце.
-
Вы создали таблицу в базе внутри контейнера без тома, затем удалили контейнер. Что с таблицей?
Изменения внутри контейнера живут, пока жив контейнер. Для данных, которые нужно сохранить, используют том.
-
Что делает часть -v pgdata:/var/lib/postgresql/data?
Слева — имя тома, справа — путь внутри контейнера. Всё, что база пишет в эту папку, сохраняется в томе.
-
Когда удобнее монтировать папку с компьютера, а не том?
Монтирование показывает контейнеру вашу папку как есть. Правка файла сразу видна внутри, без пересборки образа.