Понимание инструкции Dockerfile VOLUME
Тома Docker используются для хранения постоянных данных вне ваших контейнеров. Они позволяют файлам конфигурации, базам данных и кешам, используемым вашим приложением, пережить отдельные экземпляры контейнера.
Тома можно монтировать при запуске контейнеров с флагом -v
команды docker run
. Это может либо ссылаться на именованный том, либо привязывать каталог хоста к файловой системе контейнера.
Также можно определить тома во время сборки образа с помощью инструкции VOLUME
в файлах Docker. Этот механизм гарантирует, что контейнеры, запущенные из образа, будут иметь доступное постоянное хранилище. В этой статье вы узнаете, как использовать эту инструкцию и в каких случаях она имеет смысл.
Определение томов в Dockerfiles
Инструкция Dockerfile VOLUME
создает точку подключения тома по указанному пути к контейнеру. Том будет монтироваться из файловой системы вашего хоста Docker каждый раз при запуске контейнера.
Dockerfile в следующем примере определяет том по пути к контейнеру /opt/app/data
. Новые контейнеры автоматически подключат том к каталогу.
FROM ubuntu:22.04 VOLUME /opt/app/data
Создайте свой образ, чтобы вы могли протестировать монтирование тома:
$ docker build -t volumes-test:latest .
Получите список существующих томов в качестве ссылки:
$ docker volume ls DRIVER VOLUME NAME local demo-volume
Теперь запустите контейнер, используя тестовый образ:
$ docker run -it volume-test:latest root@07be7bde68c2:/#
Повторите команду docker volume ls
, чтобы подтвердить создание нового тома:
$ docker volume ls DRIVER VOLUME NAME local 3198bf857fdcbb8758c5ec7049f2e31a40b79e329f756a68725d83e46976b7a8 local demo-volume
Выйдите из оболочки вашего тестового контейнера, чтобы контейнер остановился:
root@07be7bde68c2:/# exit exit
Том и его данные будут по-прежнему сохраняться:
$ docker volume ls DRIVER VOLUME NAME local 3198bf857fdcbb8758c5ec7049f2e31a40b79e329f756a68725d83e46976b7a8 local demo-volume
Вы можете определить несколько томов в одной инструкции как строку с разделителями-пробелами или массив JSON. Обе следующие формы создают и монтируют два уникальных тома при запуске контейнеров:
VOLUME /opt/app/data /opt/app/config # OR VOLUME ["/opt/app/data", "/opt/app/config"]
Заполнение начального содержимого тома
Тома автоматически заполняются содержимым, помещенным в каталог монтирования на предыдущих шагах сборки образа:
FROM ubuntu:22.04 COPY default-config.yaml /opt/app/config/default-config.yaml VOLUME /opt/app/config
Этот Dockerfile определяет том, который будет инициализирован существующим файлом default-config.yaml
. Контейнер сможет читать /opt/app/config/default-config.yaml
, не проверяя, существует ли файл.
Изменения в содержимом тома, сделанные после инструкции VOLUME
, будут отброшены. В этом примере файл default-config.yaml
по-прежнему доступен после запуска контейнеров, поскольку команда rm
идет после /opt/app/config
. помечен как том.
FROM ubuntu:22.04 COPY default-config.yaml /opt/app/config/default-config.yaml VOLUME /opt/app/config RUN rm /opt/app/config/default-config.yaml
Переопределение инструкций VOLUME при запуске контейнера
Тома, созданные с помощью инструкции VOLUME
, автоматически именуются длинным уникальным хешем. Изменить их имена невозможно, поэтому может быть сложно определить, какие тома активно используются вашими контейнерами.
Вы можете предотвратить появление этих томов, вручную определив тома в своих контейнерах с помощью docker run -v
, как обычно. Следующая команда явно монтирует именованный том в каталог /opt/app/config
контейнера, делая инструкцию VOLUME
файла Dockerfile избыточной.
$ docker run -it -v config:/opt/app/config volumes-test:latest
Когда следует использовать инструкции VOLUME?
Инструкции VOLUME
могут быть полезны в ситуациях, когда вы хотите принудительно использовать постоянство, например, в образах, которые упаковывают сервер базы данных или хранилище файлов. Использование инструкций VOLUME
упрощает запуск контейнеров, не забывая применять флаги -v
.
VOLUME
также служит документацией путей к контейнерам, в которых хранятся постоянные данные. Включение этих инструкций в ваш Dockerfile позволяет любому определить, где ваш контейнер хранит свои данные, даже если они не знакомы с вашим приложением.
ОБЪЕМ Ловушки
VOLUME
не лишен недостатков. Его самая большая проблема заключается в том, как он взаимодействует со сборками изображений. Использование образа с инструкцией VOLUME
в качестве базового образа вашей сборки приведет к неожиданному поведению, если вы измените содержимое в точке подключения тома.
Предыдущая ошибка по-прежнему актуальна: эффекты команд после инструкции VOLUME
будут отброшены. Поскольку VOLUME
будет находиться в базовом образе, все в вашем собственном Dockerfile идет после инструкции, и вы не сможете изменить содержимое каталога по умолчанию. За кулисами запуск временного контейнера для сборки создаст новый том на вашем хосте, который будет уничтожен в конце сборки. Изменения не будут скопированы обратно в выходной образ.
Автоматическое монтирование томов может быть проблематичным и в других ситуациях. Иногда пользователи могут предпочесть запустить временный контейнер без каких-либо томов, возможно, в целях оценки или отладки. VOLUME
исключает эту возможность, так как невозможно отключить автоматическое монтирование. Это приводит к тому, что на хосте накапливается много избыточных томов, если контейнеры, использующие эту инструкцию, регулярно запускаются.
Краткое содержание
Инструкции Dockerfile VOLUME
позволяют определять монтирование тома во время сборки образа. Они гарантируют, что контейнеры, запущенные из образа, будут иметь доступное постоянное хранилище данных, даже если пользователь не укажет флаг -v
команды docker run
.
Такое поведение может быть полезно для образов, для которых критична сохраняемость или требуется много томов. Однако инструкция VOLUME
также нарушает некоторые ожидания пользователя и вводит уникальное поведение, поэтому ее нужно писать с осторожностью. Предоставление файла Docker Compose, который автоматически создает необходимые тома, часто является лучшим решением.