Тома: где на самом деле лежат данные контейнера
Чем именованный том отличается от привязки каталога, где всё это физически лежит на диске и как не потерять базу при пересоздании контейнера.
Обновлено 23 августа 2026 г.
Контейнер — вещь одноразовая. Всё, что записано внутрь него, исчезает вместе с ним. Данные должны жить снаружи, и способов ровно два: именованный том и привязка каталога хоста.
Два способа и когда какой
services:
db:
image: postgres:17
volumes:
- db-data:/var/lib/postgresql/data # именованный том
app:
image: nginx:1.27
volumes:
- ./site:/usr/share/nginx/html:ro # привязка каталога
- ./nginx.conf:/etc/nginx/nginx.conf:ro
volumes:
db-data:
Именованный том Docker создаёт и хранит сам, в /var/lib/docker/volumes/<имя>/_data. Права внутри выставляются образом автоматически. Так держат базы данных и внутреннее состояние сервисов.
Привязка каталога — обычный путь на диске машины. Так подкладывают файлы настройки, статику сайта, сертификаты: их удобно править редактором и хранить в репозитории.
Флаг :ro делает монтирование доступным только для чтения. Ставьте его везде, где контейнеру не нужна запись, — это дешёвая защита.
Где всё лежит физически
docker volume ls
docker volume inspect db-data
docker inspect -f '{{json .Mounts}}' <контейнер> | python3 -m json.tool
sudo du -sh /var/lib/docker/volumes/* | sort -h | tail
Последняя команда — первое, что стоит запустить, когда кончается диск. Подробнее — место на диске.
docker compose down -vиdocker volume pruneудаляют тома безвозвратно. Том с базой выглядит «неиспользуемым», пока контейнер остановлен, и попадает под очистку. Прежде чем чистить, посмотрите список:docker volume ls -f dangling=true.
Копирование и перенос
Копия именованного тома одноразовым контейнером:
docker run --rm -v db-data:/from -v $(pwd):/to alpine \
tar czf /to/db-data.tar.gz -C /from .
Восстановление:
docker volume create db-data
docker run --rm -v db-data:/to -v $(pwd):/from alpine \
tar xzf /from/db-data.tar.gz -C /to
Для баз данных этот способ подходит только при остановленном контейнере: копия работающей базы на уровне файлов может оказаться нецелостной. Правильнее выгрузка средствами самой базы — pg_dump, mysqldump. См. что именно копировать.
Права доступа
Самая частая ошибка с привязками — несовпадение владельца. Внутри контейнера процесс работает под своим UID, и файл, созданный хостом от root, ему недоступен.
docker compose exec app id
sudo chown -R 1000:1000 ./data
Многие образы принимают переменные PUID/PGID — это удобнее, чем менять владельца каталога.
Частые ошибки
- Данные писались внутрь контейнера. Пересоздали контейнер при обновлении — данные исчезли. Проверьте:
docker diff <контейнер>покажет, что изменилось в его файловой системе; крупные записи там — тревожный знак. - Привязали каталог поверх непустого пути в образе. Содержимое образа скрывается, сервис не находит своих файлов.
- Относительный путь в привязке. Он считается от каталога с
compose.yaml, а не от текущего. Запуск из другого места создаст новый пустой каталог. - Тома забыли при переустановке системы. Переустановка стирает диск целиком. Копия должна лежать не на этой машине.