Storage cheat sheet
Тома, монтирование, права, резервное копирование.
Данные в записываемом слое исчезают вместе с container'ом. Всё, что нужно сохранить, живёт в томе — и всё, что связано с этим томом дальше, Docker не делает (урок 19.1).
Содержание
- Виды монтирования
- Синтаксис
- Управление томами
- Права доступа
- Резервное копирование
- От симптома к проверке
Виды монтирования
| Вид | Где хранится | Когда |
|---|---|---|
| Именованный том | Управляется Docker | Данные эксплуатации |
| Анонимный том | То же, но без имени | Почти никогда: теряется |
| Bind mount | Указанный каталог хоста | Разработка, конфигурация |
tmpfs | Память | Временные файлы при read_only |
Именованный том переносим, bind mount привязан к конкретному каталогу конкретной машины.
Синтаксис
Краткая форма -v
docker run -v имя:/data образ # именованный том
docker run -v "$PWD:/app" образ # bind mount
docker run -v имя:/data:ro образ # только для чтения
docker run -v /data образ # анонимный том
Явная форма --mount
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
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 удаляет данные безвозвратно. Перед запуском посмотреть, что удалится:
docker volume ls -f dangling=true
Посмотреть содержимое тома, не запуская приложение:
docker run --rm -v имя:/data alpine ls -la /data
Права доступа
Пустой именованный том берёт владельца и права из каталога образа, поверх которого подключён, и только при первом подключении. Дальше том хранит их независимо.
Проверить владельца изнутри:
docker exec имя ls -ldn /data
Первое число — UID владельца, второе — GID. 0 0 означает root.
Правильное решение
RUN mkdir -p /data && chown 10001:10001 /data
USER 10001:10001
Каталог существует в образе с нужным владельцем — том его наследует.
Если том уже создан с неверными правами
docker compose down
docker volume rm проект_имя # данные будут потеряны
docker compose up -d
Либо, если данные нужны, — исправить владельца разово:
docker run --rm -v имя:/data alpine chown -R 10001:10001 /data
Чего делать не следует
docker run --rm -v имя:/data alpine chmod -R 777 /data # НЕТ
Работает и даёт полный доступ любому процессу. Права решаются владельцем, а не доступом всем.
Bind mount и права
У bind mount владелец — тот, что на хосте. Процесс в container'е должен иметь совпадающий UID:
docker run -u "$(id -u):$(id -g)" -v "$PWD:/app" образ
Подробнее: урок 7.5.
Резервное копирование
Сохранить том в архив
docker run --rm \
-v имя:/data:ro \
-v "$PWD:/backup" \
alpine tar czf /backup/имя-$(date +%F).tgz -C /data .
Восстановить
docker run --rm \
-v имя:/data \
-v "$PWD:/backup" \
alpine sh -c 'rm -rf /data/* && tar xzf /backup/имя-2026-08-04.tgz -C /data'
База данных: копировать средствами базы, а не тома
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 работает с согласованным снимком.
Правило
Резервная копия, восстановление которой не проверялось, копией не является. Проверка — восстановить в отдельный том и убедиться, что данные читаются.
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, процесс — нет |
Данные исчезли после down | docker 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'а:
docker diff имя
A — добавлено, C — изменено, D — удалено. Всё, что здесь появляется и должно сохраняться, требует тома.
Что Docker не делает с данными
Полезно держать список перед глазами: всё перечисленное — ваша задача, и она не станет проще от того, что данные в томе.
| Задача | Кто решает |
|---|---|
| Резервное копирование | Вы |
| Проверка восстановления | Вы |
| Восстановление на момент времени | Вы |
| Права на файлы | Вы |
| Перенос между машинами | Вы |
| Обновление СУБД с миграцией данных | Вы |
Отсюда практический вывод: база данных в container для эксплуатации — отдельное решение, принимаемое после ответа на все шесть вопросов, а не умолчание.
Навигация
Вернуться к справочникам
Docker CLI cheat sheet
Cleanup checklist
Раздел 07. Storage
Главное оглавление