Главная/Справочники/Справочник

Storage cheat sheet

Тома, монтирование, права, резервное копирование.

Данные в записываемом слое исчезают вместе с container'ом. Всё, что нужно сохранить, живёт в томе — и всё, что связано с этим томом дальше, Docker не делает (урок 19.1).

Содержание


Виды монтирования

ВидГде хранитсяКогда
Именованный томУправляется DockerДанные эксплуатации
Анонимный томТо же, но без имениПочти никогда: теряется
Bind mountУказанный каталог хостаРазработка, конфигурация
tmpfsПамятьВременные файлы при read_only

Именованный том переносим, bind mount привязан к конкретному каталогу конкретной машины.


Синтаксис

Краткая форма -v

bash
docker run -v имя:/data образ                # именованный том
docker run -v "$PWD:/app" образ              # bind mount
docker run -v имя:/data:ro образ             # только для чтения
docker run -v /data образ                    # анонимный том

Явная форма --mount

bash
docker run --mount type=volume,src=имя,dst=/data образ
docker run --mount type=bind,src="$PWD",dst=/app,ro образ
docker run --mount type=tmpfs,dst=/tmp,tmpfs-size=64m образ

Различие, из-за которого предпочитают --mount: если источник bind mount не существует, -v создаёт каталог, а --mount возвращает ошибку. Опечатка в пути с -v даёт пустой каталог вместо внятного отказа.

В Compose

yaml
services:
  db:
    volumes:
      - pgdata:/var/lib/postgresql/data     # именованный
      - ./config:/etc/app:ro                # bind, только чтение
      - type: tmpfs
        target: /tmp
        tmpfs: {size: 67108864}

volumes:
  pgdata:

Том, использованный и не объявленный в volumes:, становится анонимным и теряется при пересоздании.


Управление томами

ЗадачаКоманда
Списокdocker volume ls
Только неиспользуемыеdocker volume ls -f dangling=true
Создатьdocker volume create имя
Где лежит на хостеdocker volume inspect имя --format '{{.Mountpoint}}'
Кто используетdocker ps -a --filter volume=имя
Размер всех томовdocker system df -v | grep -A 100 'Local Volumes'
Удалитьdocker volume rm имя
Удалить неиспользуемыеdocker volume prune

docker volume prune удаляет данные безвозвратно. Перед запуском посмотреть, что удалится:

bash
docker volume ls -f dangling=true

Посмотреть содержимое тома, не запуская приложение:

bash
docker run --rm -v имя:/data alpine ls -la /data

Права доступа

Пустой именованный том берёт владельца и права из каталога образа, поверх которого подключён, и только при первом подключении. Дальше том хранит их независимо.

Проверить владельца изнутри:

bash
docker exec имя ls -ldn /data

Первое число — UID владельца, второе — GID. 0 0 означает root.

Правильное решение

dockerfile
RUN mkdir -p /data && chown 10001:10001 /data
USER 10001:10001

Каталог существует в образе с нужным владельцем — том его наследует.

Если том уже создан с неверными правами

bash
docker compose down
docker volume rm проект_имя      # данные будут потеряны
docker compose up -d

Либо, если данные нужны, — исправить владельца разово:

bash
docker run --rm -v имя:/data alpine chown -R 10001:10001 /data

Чего делать не следует

bash
docker run --rm -v имя:/data alpine chmod -R 777 /data   # НЕТ

Работает и даёт полный доступ любому процессу. Права решаются владельцем, а не доступом всем.

Bind mount и права

У bind mount владелец — тот, что на хосте. Процесс в container'е должен иметь совпадающий UID:

bash
docker run -u "$(id -u):$(id -g)" -v "$PWD:/app" образ

Подробнее: урок 7.5.


Резервное копирование

Сохранить том в архив

bash
docker run --rm \
  -v имя:/data:ro \
  -v "$PWD:/backup" \
  alpine tar czf /backup/имя-$(date +%F).tgz -C /data .

Восстановить

bash
docker run --rm \
  -v имя:/data \
  -v "$PWD:/backup" \
  alpine sh -c 'rm -rf /data/* && tar xzf /backup/имя-2026-08-04.tgz -C /data'

База данных: копировать средствами базы, а не тома

bash
docker compose exec -T db pg_dump -U app appdb | gzip > дамп-$(date +%F).sql.gz
gunzip -c дамп-2026-08-04.sql.gz | docker compose exec -T db psql -U app appdb

Почему. Архив тома, снятый с работающей базы, может оказаться несогласованным: часть страниц записана, часть нет. Останавливать базу ради копии обычно нельзя, а pg_dump работает с согласованным снимком.

Правило

Резервная копия, восстановление которой не проверялось, копией не является. Проверка — восстановить в отдельный том и убедиться, что данные читаются.

bash
docker volume create проверка
docker run --rm -v проверка:/data -v "$PWD:/backup" \
  alpine tar xzf /backup/имя-2026-08-04.tgz -C /data
docker run --rm -v проверка:/data alpine ls -la /data | head
docker volume rm проверка

Подробнее: урок 7.6.


От симптома к проверке

СимптомПроверкаВероятная причина
Permission denied при записиdocker exec имя ls -ldn /dataВладелец тома — root, процесс — нет
Данные исчезли после downdocker volume lsТом анонимный или использован -v
Приложение не находит свои файлыdocker run --rm образ ls /app без монтированияBind mount накрыл каталог образа
Данные не сохраняютсяdocker inspect имя --format '{{json .Mounts}}'Запись идёт мимо тома
read_only ломает стартdocker diff имяПриложение пишет туда, где нет тома
Место кончилосьdocker system df -vТома или логи
Изменения в коде не видныdocker inspect --format '{{json .Mounts}}'Смонтирован не тот путь

docker diff — недооценённая команда. Показывает, что приложение записало в слой container'а:

bash
docker diff имя

A — добавлено, C — изменено, D — удалено. Всё, что здесь появляется и должно сохраняться, требует тома.


Что Docker не делает с данными

Полезно держать список перед глазами: всё перечисленное — ваша задача, и она не станет проще от того, что данные в томе.

ЗадачаКто решает
Резервное копированиеВы
Проверка восстановленияВы
Восстановление на момент времениВы
Права на файлыВы
Перенос между машинамиВы
Обновление СУБД с миграцией данныхВы

Отсюда практический вывод: база данных в container для эксплуатации — отдельное решение, принимаемое после ответа на все шесть вопросов, а не умолчание.


Навигация

Вернуться к справочникам
Docker CLI cheat sheet
Cleanup checklist
Раздел 07. Storage
Главное оглавление

Markdown на GitHub ↗