Как сохранять данные в Docker: тома (volumes), bind mounts и tmpfs
В Docker все данные внутри контейнера временные и существуют только пока он активен.
При остановке или удалении контейнера базы данных, логи и любые другие файлы стираются. Чтобы этого не произошло, данные из контейнера нужно сохранять на сервере.
В этом руководстве будет рассмотрен способ сохранения пользовательских данные с помощью Docker volumes — механизм постоянного хранения Docker. Также рассмотрим альтернативы: bind mounts и tmpfs. Дополнительно разберём как настроить автоматический перезапуск контейнеров после сбоев или перезагрузки Raspberry Pi с помощью стратегий restart: unless-stopped, always, on-failure и других.
Типы хранения данных Docker
В Docker есть несколько способов сохранить информацию на хосте:
Использование Docker Volume
Volume — это директория, которая не зависит от жизненного цикла контейнера. Управляет ею сам Docker. Данные хранятся в /var/lib/docker/volumes/ и могут быть подключены к одному или нескольким контейнерам при запуске.
Разберем основные команды управления томами.
docker volume create my_volumedocker volume lsdocker volume inspect my_volumedocker volume rm my_volumeПодключение Docker Volume к контейнеру через docker run
Разберем на примере, как работает подключение volume к контейнеру. Для этого запустим контейнер PostgreSQL и подключим базу данных и его настройки к Docker volume:
docker run -d --name pg_db -v pg_data:/var/lib/postgresql/data postgresЕсли volume pg_data не существует, Docker создаст его при запуске команды. Как правило в описании официального образа на Docker Hub указано, какие пути внутри контейнера нужно монтировать для сохранения данных.
Как использовать volume в docker-compose.yml
Для многоконтейнерных приложений (например, веб-сервер + база данных) важно обеспечить постоянное хранение данных. В docker-compose.yml можно создать отдельную секцию для volumes и описать, какие директории контейнера нужно связать с томами на хосте:
services:
db:
image: postgres:15
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:^O Записать ^X ВыходПри запуске файла командой docker compose up -d произойдет то же самое, что и при подключении volume командой docker run. Том db_data на хосте будет связан с директорией /var/lib/postgresql/data внутри контейнера. Все данные PostgreSQL будут сохраняться в этом томе даже после удаления контейнера.
Просмотр содержимого Volume через временный контейнер
Чтобы посмотреть данные внутри volume, достаточно запустить одноразовый контейнер:
docker run -v my_vol:/data alpine ls /dataЭтот способ считается рекомендованным и безопаснее прямого доступа к файлам на хосте: не нужно останавливать контейнер, а значит, исключен риск повреждения данных активной базы.
Backup именованных Volume
Любому активному приложению необходим бэкап: не только для сохранения данных, но и для переноса на другое устройство. Для этого используется утилита tar, которая создаст копию volume и упакует её в архив:
docker run --rm -v pg_data:/volume -v $(pwd):/backup alpine \
tar czf /backup/pg_data.tar.gz -C /volume .Основные параметры:
Команда архивации:
Флаги tar:
Использование Bind mounts
Кроме именованных томов (volumes), Docker позволяет напрямую монтировать любую папку или файл с вашего компьютера (хост-машины) внутрь контейнера. Такой способ называется bind mount.
Bind mounts для директории
Это прямое монтирование произвольной папки с хоста в контейнер, минуя управление через Docker. Вы сами указываете точный путь на своем компьютере.
Синтаксис почти идентичен именованным томам. Единственное отличие — вместо имени volume указываем прямой путь к папке на хост-машине:
docker run -d --name pg_db -v /home/user/pg_data:/var/lib/postgresql/data postgresЧасть /var/lib/postgresql/data идентична монтированию через volume, так как путь хранения данных внутри контейнера остается неизменным. Отличие лишь в источнике: вместо имени pg_data мы указываем реальный путь на хосте — /home/user/pg_data.
Директорию pg_data на хосте лучше создать заранее, иначе Docker создаст её автоматически от имени root, что может привести к проблемам с правами доступа.
Bind mounts для файлов
По аналогии с монтированием директории можно смонтировать любой отдельный файл. Все изменения файла на хост-машине будут сразу отражаться внутри контейнера.
docker run -v $(pwd)/hello.py:/app/hello.py python:3.11 python /app/hello.pyПараметр -v $(pwd)/hello.py:/app/hello.py монтирует питон-скрипт hello.py из текущей папки на вашем компьютере внутрь контейнера по пути /app/hello.py.
$(pwd) — это сокращение от «print working directory», то есть «путь к той папке, где вы сейчас находитесь в терминале.
При запуске обычного питон — скрипта контейнер стартует, выполняет скрипт и сразу завершает работу, так как отсутствует долгоживущий процесс.
Использование Bind mounts внутри docker-compose.yml
Bind mounts можно использовать и в Compose. Для демонстрации работы возьмем Dockerfile и Python — скрипт hello.py из прошлой статьи и разместим их в папке app рядом с docker-compose.yml:

Теперь соберем docker-compose.yml и укажем абсолютный или относительный путь вместо имени тома:
services:
hello-python:
build: ./app
volumes:
- ./app/hello.py:/app/hello.py:ro^O Записать ^X ВыходЛюбое изменение в скрипте hello.py на хосте будет сразу отображаться в запущенном контейнере. Суффикс :ro (read-only) нужен чтобы контейнер только читал файл hello.py, но не мог изменять его.
Использование tmpfs mounts
Этот способ хранения данных, в отличие от volumes и bind mounts, никогда не производит запись на диск. Все изменения хранятся только в оперативной памяти (RAM) хост-машины и пропадают после остановки или перезагрузки контейнера.
Когда это может пригодиться:
Как использовать tmpfs mount с docker run
Запустить контейнер с tmpfs-директорией можно с помощью флага --tmpfs:
docker run -d --tmpfs /tmp/cache alpine tail -f /dev/nullРазберём команду:
Всё, что приложение запишет в папку /tmp/cache, исчезнет сразу после остановки контейнера. При этом остальные данные, сохранённые через volumes или bind mounts, останутся на месте.
Как использовать tmpfs mount в docker-compose.yml
В docker-compose.yml tmpfs задаётся отдельной секцией tmpfs, а не через параметр volumes:
services:
hello-python:
build: ./app
tmpfs:
- /tmp/cache^O Записать ^X ВыходМожно также добавить некоторые опции монтирования через двоеточие:
services:
hello-python:
build: ./app
tmpfs:
- /tmp/cache:rw,noexec,nosuid,size=64m^O Записать ^X ВыходДля tmpfs доступен следующий набор опций:
Tmpfs не нужен в каждом проекте, но незаменим в сценариях, где важны безопасность, скорость или гарантированное удаление данных после остановки контейнера.
Главное правило: если данные не должны пережить перезапуск и должны оставаться только в памяти — используйте tmpfs.
Итоги: тома (volumes), bind mounts и tmpfs
В этой статье мы разобрали три способа хранения данных в Docker: именованные тома (volumes) для постоянного хранения, bind mounts для прямого доступа к файлам хоста и tmpfs для временных данных в оперативной памяти. Научились выбирать подходящий тип монтирования в зависимости от задачи: безопасность, производительность или сохранность данных.
