Я изучаю Docker и сомневаюсь, когда и где использовать ADD
и VOLUME
. Вот что, я думаю, делают оба:
ДОБАВИТЬ
Скопируйте файлы в образ во время сборки. В образе есть все файлы, поэтому его можно очень легко развернуть. С другой стороны, необходимость сборки каждый раз не выглядит хорошей идеей при разработке, потому что для сборки требуется, чтобы разработчик запускал команду для перестройки контейнера; кроме того, строительство контейнера может занять много времени.
ОБЪЕМ
Я понимаю, что с помощью docker run -v
вы можете смонтировать папку хоста внутри вашего контейнера, таким образом вы можете легко изменять файлы и наблюдать, как приложение в вашем контейнере реагирует на изменения. Он отлично выглядит в разработке, но я не уверен, как развернуть мои файлы таким образом.
COPY
чтобыADD
. Они почти одинаковы, ноADD
имеют некоторые дополнительные возможности по отношению к URL-адресам и файлам архивов, что может удивить.Ответы:
ДОБАВИТЬ
Фундаментальное различие между ними заключается в том, что
ADD
все, что вы добавляете, будь то папка или просто файл, становится частью вашего изображения . Любой, кто использует созданное вами изображение, получит доступ ко всему, что выADD
. Это верно, даже если вы впоследствии удалите его, потому что Docker работает в слоях, иADD
слой по-прежнему будет существовать как часть изображения. Чтобы было ясно, вы толькоADD
что-то делаете во время сборки и никогда не можетеADD
во время выполнения.Несколько примеров случаев, когда вы хотите использовать
ADD
:ADD ./requirements.txt /requirements.txt
а затемRUN pip install -r /requirements.txt
Вы хотите использовать код вашего приложения в качестве контекста в вашем Dockerfile, например, если вы хотите установить каталог вашего приложения в качестве рабочего каталога в вашем образе и чтобы команда по умолчанию в контейнере, запускаемом из вашего образа, фактически запускала ваше приложение, вы сможет сделать:
ADD ./ /usr/local/git/my_app
WORKDIR /usr/local/git/my_app
CMD python ./main.py
ОБЪЕМ
Том, с другой стороны, просто позволяет контейнеру, запускаемому из вашего образа, иметь доступ к некоторому пути на любом локальном компьютере, на котором выполняется контейнер. Вы не можете использовать файлы из своего
VOLUME
каталога в Dockerfile . Все, что находится в вашем каталоге тома, не будет доступно во время сборки, но будет доступно во время выполнения .Несколько примеров случаев, когда вы хотите использовать
VOLUME
:/var/log/my_app
. Вы хотите, чтобы эти журналы были доступны на главном компьютере и не удалялись при удалении контейнера. Вы можете сделать это, создав точку монтирования в/var/log/my_app
, добавивVOLUME /var/log/my_app
в свой Dockerfile, а затем запустив свой контейнер сdocker run -v /host/log/dir/my_app:/var/log/my_app some_repo/some_image:some_tag
VOLUME /etc/settings/my_app_settings
в Dockerfile, запустить контейнерdocker run -v /host/settings/dir:/etc/settings/my_app_settings some_repo/some_image:some_tag
и убедиться, что каталог / host / settings / существует во всех средах, в которых вы ожидаете запускать приложение.источник
docker run -v $HOST_PATH:$CONTAINER_PATH node:latest node $CONTAINER_PATH/app.js
.VOLUME
Инструкция создает объем данных в вашем Докер контейнере во время выполнения. Каталог, указанный в качестве аргумента,VOLUME
является каталогом, который обходит файловую систему Union и в основном используется для постоянных и общих данных.Если вы запустите
docker inspect <your-container>
, вы увидите, что вMounts
разделе есть значок,Source
который представляет расположение каталога на хосте, и значок,Destination
который представляет местоположение смонтированного каталога в контейнере. Например,Вот 3 варианта использования
docker run -v
:docker run -v /data
: Это аналогично указаниюVOLUME
инструкции в вашем Dockerfile.docker run -v $host_path:$container_path
: Это позволяет вам подключаться$host_path
с вашего хоста к$container_path
вашему контейнеру во время выполнения. При разработке это полезно для совместного использования исходного кода на вашем хосте с контейнером. В производстве это можно использовать для монтирования таких вещей, как информация DNS хоста (находится в/etc/resolv.conf
) или секреты в контейнер. И наоборот, вы также можете использовать этот метод для записи журналов контейнера в определенные папки на хосте. Оба$host_path
и$container_path
должны быть абсолютными путями.docker run -v my_volume:$container_path
: Это создает том данных в вашем контейнере$container_path
и дает ему имяmy_volume
. По сути, это то же самое, что создание и присвоение имени тому usingdocker volume create my_volume
. Такое присвоение имени тому полезно для тома данных контейнера и тома общего хранилища с использованием драйвера хранилища с несколькими хостами, такого как Flocker .Обратите внимание, что способ подключения папки хоста в качестве тома данных недоступен в Dockerfile. Чтобы процитировать документацию докера ,
Теперь, если вы хотите скопировать свои файлы в контейнеры в среде, не связанной с разработкой, вы можете использовать инструкции
ADD
илиCOPY
в своем файле Dockerfile. Это то, что я обычно использую для развертывания, не связанного с разработкой.источник
ADD
инструкции в вашем Dockerfile, поскольку она выполняется толькоdocker build
командой. Это необходимо, когда другие создают ваш контейнер впервые, и когда вы готовы развернуть его в других средах, не связанных с разработкой.-v
команду для разработки, а другой файл докеров создать образ, включающий файлы сADD
для развертывания?ADD
любом случае, сколько времени занимает сборка с помощью ? Всего пару секунд? Если у вас есть два файла Dockerfile, и вы делитесь ими с другими (или публикуете его в реестре Docker ), какой из них используется по умолчанию? У вас возникнут дополнительные накладные расходы на обслуживание, чтобы убедиться, что нужный Dockerfile по умолчанию попадает к нужным пользователям. Но в конце концов вы решаете, что лучше всего подходит для вас. Лично мне нравится, чтобы был один и только один Dockerfile для создания моего контейнера.