ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

Docker volumes: backup/restore, prune и bind-mount — практический гид

Docker volumes кажутся простыми, пока не понадобятся бэкап, перенос на другой сервер или чистка диска. Разбираем volume vs bind-mount, надёжные команды backup/restore через tar, безопасный docker prune и типовые проблемы с permissions и uid/gid.
Docker volumes: backup/restore, prune и bind-mount — практический гид

Docker volumes кажутся простыми ровно до того момента, пока не понадобятся бэкап, перенос на другой сервер или «чистка диска» после пары месяцев разработки. Ниже — рабочие схемы, которые реально помогают в проде: как делать бэкап/восстановление volume без привязки к внутренностям Docker, как выбирать между volume и bind-mount, чем опасен docker prune и почему «странные» ошибки почти всегда упираются в permissions, uid и gid.

Volume и bind-mount: что выбрать в реальной жизни

У Docker есть два самых популярных способа подмонтировать данные в контейнер:

  • Docker volume — именованное хранилище, которым управляет Docker. Обычно лежит в /var/lib/docker/volumes (если не меняли data-root).
  • Bind mount — «проброс» конкретной директории хоста в контейнер (например, /srv/app/uploads/var/www/uploads).

Bind mount vs volume: практическое сравнение

Docker volume удобен, когда вы хотите абстрагироваться от путей на хосте: переносите проект между серверами, крутите несколько окружений, используете CI и хотите меньше ручного сопровождения. Volume проще бэкапить стандартными приёмами через временный контейнер, и он меньше привязан к структуре каталогов хоста.

Bind mount полезен, когда данные должны быть явно в предсказуемом месте на хосте: для прямого доступа утилитами хоста, для интеграции с существующими бэкапами, для логов в каталог под logrotate, для разработки (чтобы изменения в коде сразу были видны в контейнере без пересборки).

Для продакшена часто выигрывает гибрид: база и критичные stateful-данные держим в volume, а конфиги/сертификаты/артефакты — в bind mount в каталогах вроде /srv/project/.

Как быстро понять, что именно используется

Посмотреть монтирования конкретного контейнера:

docker inspect --format '{{ json .Mounts }}' my_container

Список volumes:

docker volume ls

Где физически лежат данные volume (поле Mountpoint):

docker volume inspect my_volume

Backup volume: надёжный бэкап без магии

Задача бэкапа volume — упаковать содержимое в архив и сохранить в понятное место (например, /srv/backups). Самый переносимый способ: запустить временный контейнер, примонтировать volume и каталог для бэкапа, выполнить tar.

Бэкап volume в tar.gz (универсальный вариант)

Пример: volume pgdata, бэкапы кладём в /srv/backups/docker:

mkdir -p /srv/backups/docker
docker run --rm -v pgdata:/data -v /srv/backups/docker:/backup alpine sh -c 'cd /data && tar -czf /backup/pgdata.tar.gz .'

Плюсы подхода:

  • не зависит от ОС и утилит внутри «боевого» контейнера;
  • не требует знать реальный путь Mountpoint на хосте;
  • архив легко переносится и восстанавливается на другом сервере.

Важно про права: permissions, uid/gid

Данные в volume часто принадлежат не root (например, Postgres с uid=999). Если бэкап/restore сделаны без учёта владельцев, после миграции ловите permission denied.

Практика простая:

  • архивируйте/распаковывайте внутри временного контейнера, который запускается от root (так tar корректно восстановит владельцев и режимы);
  • если после восстановления права всё равно «не те», делайте явный chown по нужному uid/gid.

Консистентность: бэкапить «на горячую» или останавливать контейнер?

Для статических данных (uploads, артефакты) бэкап на лету обычно нормален. Для СУБД и любых stateful-сервисов выбирайте один из вариантов:

  • логический дамп (pg_dump, mysqldump) — консистентно, но может быть дольше;
  • остановка контейнера на время архивации — самый простой вариант, но с простоем;
  • механизмы hot backup самой СУБД — лучший вариант для продакшена.

Если вы строите регулярные бэкапы PostgreSQL «по-взрослому», пригодится отдельная схема с PITR/WAL: PITR для PostgreSQL: WAL, восстановление и типовые ошибки.

Схема сравнения Docker volume и bind mount на практике

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Restore volume: как восстановить из архива

«Docker restore» для volumes — это не отдельная команда, а процедура: создать (или очистить) volume и распаковать туда архив.

Восстановление в новый volume

Создаём volume:

docker volume create pgdata

Распаковываем архив:

docker run --rm -v pgdata:/data -v /srv/backups/docker:/backup alpine sh -c 'cd /data && tar -xzf /backup/pgdata.tar.gz'

Если восстанавливаете в существующий volume, сначала остановите все контейнеры, которые его используют. Иначе получите гонки и частично перезаписанное состояние.

Как аккуратно очистить volume перед restore

Вариант 1 (самый простой): удалить и создать заново:

docker stop my_db
docker volume rm pgdata
docker volume create pgdata

Вариант 2: очистить содержимое (когда удалять volume нельзя из-за зависимостей/оркестрации):

docker stop my_db
docker run --rm -v pgdata:/data alpine sh -c 'rm -rf /data/* /data/.[!.]* /data/..?*'

Быстрая проверка после восстановления

  • есть ожидаемые файлы;
  • владельцы и режимы файлов выглядят адекватно;
  • контейнер стартует без ошибок доступа.

Посмотреть права внутри volume:

docker run --rm -v pgdata:/data alpine sh -c 'ls -la /data | head'

Permissions и uid/gid: почему после переноса всё ломается

Классика: volume восстановили, контейнер стартует и падает с «permission denied» или «could not open file». В большинстве случаев причина одна: несовпадение владельцев/прав с тем, от какого пользователя реально запускается процесс в контейнере.

Почему имена пользователей не важны

В Linux права завязаны на числа: uid и gid. Имя пользователя (например, postgres) — это только отображение через /etc/passwd внутри конкретной системы/образа. Volume хранит именно числовые идентификаторы, поэтому «postgres» в разных образах может иметь разные uid.

Как узнать uid/gid процесса в контейнере

Если контейнер живой:

docker exec my_container id

Если контейнер не стартует, проверьте образ через временный запуск:

docker run --rm --entrypoint sh my_image -c 'id'

Как быстро починить права после restore

Два рабочих пути:

  • chown внутри временного контейнера с примонтированным volume (универсально);
  • chown на хосте по пути Mountpoint (быстро, но привязываетесь к внутренностям Docker и рискуете ошибиться путём).

Пример: назначить владельцем uid=999, gid=999:

docker run --rm -v pgdata:/data alpine sh -c 'chown -R 999:999 /data'

Если сервис ожидает строгие режимы каталогов (например, 0700), добавьте настройку прав отдельно:

docker run --rm -v pgdata:/data alpine sh -c 'chmod 0700 /data'

docker prune: как чистить диск и не удалить нужное

docker prune — набор команд для удаления неиспользуемых объектов: контейнеров, образов, сетей, build cache и volumes. Подвох в том, что «неиспользуемый» для Docker означает «не привязан ни к одному контейнеру». Если вы удалили контейнер, но данные хотели сохранить, volume быстро становится «осиротевшим» и попадает под удаление.

Какие prune-команды бывают

  • docker container prune — остановленные контейнеры.
  • docker image prune — неиспользуемые образы.
  • docker network prune — неиспользуемые сети.
  • docker volume prune — неиспользуемые volumes (самое рискованное).
  • docker system prune — комплексная чистка (опасно без инвентаризации).

Перед volume prune: инвентаризация

Список volumes:

docker volume ls

Какие контейнеры используют конкретный volume:

docker ps -a --filter volume=pgdata

Если команда ничего не выводит, volume не привязан ни к одному контейнеру и будет кандидатом на удаление.

Почему docker system prune «внезапно» ломает окружение

  • удалились образы, и при рестарте/деплое их пришлось заново тянуть (время, трафик);
  • удалились volumes, которые на момент чистки «временно не были подключены» (вы удалили контейнер для пересоздания);
  • удалился build cache, и сборки стали заметно дольше.

Перед чисткой полезно понять, что именно съедает место:

docker system df

Если сомневаетесь, нужен volume или нет, сначала сделайте tar-бэкап. Ошибка при удалении почти всегда дороже лишнего архива.

Рабочие схемы бэкапа для продакшена

Ниже — несколько шаблонов, которые обычно переживают рост проекта и миграции.

Шаблон 1: volume → tar → ротация на хосте

Хорош для небольших проектов: прозрачно, переносимо, минимум зависимостей. Автоматизацию (cron/systemd timer) и ротацию делаете сами.

Пример (каждая команда — отдельной строкой):

mkdir -p /srv/backups/docker
TS=$(date +%F_%H%M%S)
docker run --rm -v pgdata:/data -v /srv/backups/docker:/backup alpine sh -c "cd /data && tar -czf /backup/pgdata_${TS}.tar.gz ."

Если вы хотите хранить бэкапы в S3-совместимом хранилище и делать ротацию «по уму», пригодится обзор практичных инструментов: S3-бэкапы: restic/borg и типовые схемы хранения.

Шаблон 2: данные в bind mount → бэкап средствами хоста

Если у вас уже есть системный бэкап, bind mount упрощает интеграцию: данные лежат в /srv или /var и попадают в существующие задания. Минус — нужно дисциплинированно поддерживать права и политики безопасности (SELinux/AppArmor), если они включены.

Шаблон 3: гибрид (часто лучший)

Volume для того, что «живёт в Docker» (БД, очереди, состояние), а bind mount — для того, что нужно видеть/редактировать на хосте (конфиги, сертификаты, кастомные скрипты, каталоги обмена). Если проект живёт на одном узле, обычно достаточно хорошего VDS, где вы контролируете диски, бэкапы и расписания.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Чек-лист миграции на другой сервер

  1. Зафиксируйте список volumes: docker volume ls.

  2. Снимите бэкап каждого критичного volume в архив.

  3. Сохраните compose-файлы/манифесты и переменные окружения (в отдельное защищённое место).

  4. На новом сервере создайте volumes и выполните restore.

  5. Проверьте permissions: владельцев, режимы, фактические uid/gid процесса в контейнере.

  6. Только после проверки запускайте сервисы и переключайте трафик.

Чек-лист миграции Docker volumes на новый сервер с бэкапами в tar.gz

Частые ошибки и быстрые диагнозы

«Volume пустой, хотя данные должны быть»

Обычно вы смонтировали не тот volume или перепутали путь в контейнере. Проверьте:

docker volume inspect my_volume
docker inspect my_container --format '{{ json .Mounts }}'

После restore приложение создаёт новые файлы, но не читает старые

Почти всегда это uid/gid. Сравните владельцев файлов в volume и пользователя процесса в контейнере, затем сделайте chown.

«docker volume prune удалил нужное»

Docker удалил «неиспользуемые» volumes (не привязанные к контейнерам). На будущее: перед пересозданием контейнеров держите правило «сначала бэкап». А агрессивные чистки на проде запускайте только после инвентаризации.

Итоги

Volumes — правильный способ хранить состояние контейнеров, но относиться к ним нужно как к данным: делать регулярный бэкап, понимать процедуру restore, аккуратно применять prune и всегда держать в голове permissions, uid и gid. Один раз выстроите понятный процесс бэкапа/восстановления и дисциплину чистки — и Docker перестанет «съедать диск» и «ломаться после миграции».

Поделиться статьей

Вам будет интересно

Incident response для сайта: что делать, если website hacked и найден malware OpenAI Статья написана AI (GPT 5)

Incident response для сайта: что делать, если website hacked и найден malware

Если сайт взломали, действуйте по плану: быстро изолируйте узел, сохраните логи и артефакты до чистки, выполните log review, убери ...
Linux sockets: somaxconn, backlog и лимиты файлов (fs.file-max, ulimit nofile) OpenAI Статья написана AI (GPT 5)

Linux sockets: somaxconn, backlog и лимиты файлов (fs.file-max, ulimit nofile)

При пиках трафика ошибки Connection refused и таймауты возникают даже на сильном сервере из‑за переполнения backlog и лимитов FD. ...
IPv6 DNS: AAAA и reverse DNS (ip6.arpa) — практическая настройка и диагностика OpenAI Статья написана AI (GPT 5)

IPv6 DNS: AAAA и reverse DNS (ip6.arpa) — практическая настройка и диагностика

Пошагово разбираем DNS для IPv6: как публиковать AAAA, как устроен reverse DNS в ip6.arpa и как собрать PTR-имя из IPv6-адреса. Да ...