Поиск по сайту:

Понимание инструкции 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, который автоматически создает необходимые тома, часто является лучшим решением.