Перейти к содержимому
VDS · Docker и контейнеры

Тома: где на самом деле лежат данные контейнера

Чем именованный том отличается от привязки каталога, где всё это физически лежит на диске и как не потерять базу при пересоздании контейнера.

Обновлено 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, а не от текущего. Запуск из другого места создаст новый пустой каталог.
  • Тома забыли при переустановке системы. Переустановка стирает диск целиком. Копия должна лежать не на этой машине.