Как монтировать Тома хоста в контейнеры docker в Dockerfile во время сборки
оригинальный вопрос: Как использовать инструкцию Тома в Dockerfile?
исправлено: обновление из ответа ниже, поэтому фактический вопрос, который я хочу решить, - как монтировать Тома хоста в контейнеры docker в Dockerfile во время сборки, т. е., имея docker run -v /export:/export возможность во docker build.
Последнее Обновление: было решение -- rocker, которое не было от Docker, но теперь, когда rocker прекращен, я возвращаю ответ назад к "не представляется возможным" снова.
обновление: так что ответ "не возможно". Я могу принять это как ответ, поскольку я знаю, что этот вопрос широко обсуждался в https://github.com/docker/docker/issues/3156. я могу понять, что переносимость является первостепенной проблемой для разработчика docker; но как пользователь docker, я должен сказать, что я очень разочарован этой отсутствующей функцией. Позвольте мне закончить свой аргумент цитатой из вышеупомянутого обсуждение: "Я хотел бы использовать Gentoo в качестве базового изображения, но определенно не хочу, чтобы > 1 ГБ данных дерева переноса находились в любом из слоев после создания изображения. Вы могли бы иметь некоторые хорошие компактные контейнеры, если бы не гигантское дерево переноса, которое должно появиться в образе во время установки. " Да, я могу использовать wget или curl для загрузки всего, что мне нужно, но тот факт, что просто соображение переносимости теперь заставляет меня загружать > 1 ГБ дерева переноса каждый раз, когда я создание базового образа Gentoo не является ни эффективным, ни удобным для пользователя. Более того, репозиторий пакетов всегда будет находиться под /usr/portage, поэтому всегда переносится под Gentoo. Опять же, я уважаю это решение, но, пожалуйста, позвольте мне выразить свое разочарование, а также в то же время. Спасибо.
исходный вопрос в деталях:
С
общий доступ к каталогам через Volumes
http://docker.readthedocs.org/en/v0.7.3/use/working_with_volumes/
в нем говорится, что функция томов данных "была доступна с версии 1 удаленного API Docker". Мой докер версии 1.2.0, но я нашел пример, приведенный в вышеуказанной статье не работает:
# BUILD-USING: docker build -t data .
# RUN-USING: docker run -name DATA data
FROM busybox
VOLUME ["/var/volume1", "/var/volume2"]
CMD ["/usr/bin/true"]
как правильно в Dockerfile монтировать Тома, смонтированные на хосте, в контейнеры docker с помощью команды VOLUME?
$ apt-cache policy lxc-docker
lxc-docker:
Installed: 1.2.0
Candidate: 1.2.0
Version table:
*** 1.2.0 0
500 https://get.docker.io/ubuntu/ docker/main amd64 Packages
100 /var/lib/dpkg/status
$ cat Dockerfile
FROM debian:sid
VOLUME ["/export"]
RUN ls -l /export
CMD ls -l /export
$ docker build -t data .
Sending build context to Docker daemon 2.56 kB
Sending build context to Docker daemon
Step 0 : FROM debian:sid
---> 77e97a48ce6a
Step 1 : VOLUME ["/export"]
---> Using cache
---> 59b69b65a074
Step 2 : RUN ls -l /export
---> Running in df43c78d74be
total 0
---> 9d29a6eb263f
Removing intermediate container df43c78d74be
Step 3 : CMD ls -l /export
---> Running in 8e4916d3e390
---> d6e7e1c52551
Removing intermediate container 8e4916d3e390
Successfully built d6e7e1c52551
$ docker run data
total 0
$ ls -l /export | wc
20 162 1131
$ docker -v
Docker version 1.2.0, build fa7b24f
7 ответов:
Это не возможно, чтобы использовать
VOLUMEинструкция сказать докер что смонтировать. Это серьезно нарушило бы переносимость. Эта инструкция сообщает docker, что содержимое в этих каталогах не входит в изображения и может быть доступно из других контейнеров с помощью--volumes-fromпараметр командной строки. Вы должны запустить контейнер с помощью-v /path/on/host:/path/in/containerдля доступа к каталогам с хоста.подключение томов хоста во время сборки невозможно. Нет привилегированной сборки и установка хоста также серьезно ухудшит переносимость. Вы можете попробовать использовать wget или curl для загрузки всего, что вам нужно для сборки, и поместить его на место.
UPDATE: кто-то просто не примет нет в качестве ответа, и мне это очень нравится, особенно на этот конкретный вопрос.
хорошие новости, теперь есть способ--
решение Rocker:https://github.com/grammarly/rocker
Джон Яни сказал, "ИМО, он решает все слабые места файла Docker, что делает его пригодным для развитие."
качелька
https://github.com/grammarly/rocker
вводя новые команды, Rocker стремится решить следующие случаи использования, которые являются болезненными с простым Докером:
- монтировать многоразовые Тома на этапе сборки, поэтому инструменты управления зависимостями могут использовать кэш между сборками.
- поделиться ssh ключами со сборкой (для вытягивания частных репозиториев и т. д.), а не оставляя их в полученное изображение.
- построить и запустить приложение в разных образах, иметь возможность легко передавать артефакт от одного изображения к другому, в идеале иметь эту логику в одном файле Dockerfile.
- Tag / Push изображения прямо из Dockerfiles.
- передать переменные из команды сборки оболочки, чтобы они могли быть заменены на Dockerfile.
и многое другое. Это самые критические вопросы, которые блокировали наше принятие Docker на Это дополнение не совместимо.
есть способ монтировать том во время сборки, но он не включает Dockerfiles.
техника будет создать контейнер из любой базы, которую вы хотели использовать (установка вашего Тома(ов) в контейнере с
-voption), запустите сценарий оболочки, чтобы выполнить работу по созданию образа, а затем совершить контейнер как изображение, когда сделано.Это не только оставит лишние файлы, которые вы не хотите (это хорошо для безопасности файлы, а также, как SSH файлы), он также создает один образ. У него есть недостатки: команда commit не поддерживает все инструкции Dockerfile, и она не позволяет вам забрать, когда вы остановились, если вам нужно отредактировать сценарий сборки.
при запуске контейнера создается каталог на вашем Хосте и монтируется в контейнер. Вы можете узнать, что это за каталог с
$ docker inspect --format "{{ .Volumes }}" <ID> map[/export:/var/lib/docker/vfs/dir/<VOLUME ID...>]Если вы хотите смонтировать каталог с вашего хоста внутри вашего контейнера, вы должны использовать
Я думаю, что вы можете сделать то, что вы хотите сделать, запустив сборку с помощью команды docker, которая сама запускается внутри контейнера docker. Смотрите Docker теперь может работать в Docker / Docker Blog. Такая техника, но которая фактически обращалась к внешнему докеру из контейнера, использовалась, например, при изучении того, как создать наименьший возможный контейнер Docker / Xebia Blog.
еще одна соответствующая статья Настройки Оптимизации Изображений | CenturyLink Labs, что объясняет, что если вы в конечном итоге загружаете материал во время сборки, вы можете избежать потери пространства в конечном изображении, загрузив, создав и удалив загрузку за один шаг.
это некрасиво, но я добился подобия этого вот так:
Dockerfile:
FROM foo COPY ./m2/ /root/.m2 RUN stuffimageBuild.sh:
docker build . -t barImage container="$(docker run -d barImage)" rm -rf ./m2 docker cp "$container:/root/.m2" ./m2 docker rm -f "$container"у меня есть сборка java, которая загружает вселенную в /root/.м2, и сделал так каждый раз.
imageBuild.shкопирует содержимое этой папки на хост после сборки, иDockerfileкопирует их обратно в образ для следующей сборки.Это что-то вроде того, как Том будет работать (т. е. он сохраняется между сборками).
во-первых, чтобы ответить "почему бы и нет
VOLUMEработы?"Когда вы определяетеVOLUMEв файле Dockerfile можно определить только цель, а не источник Тома. Во время сборки вы получите только анонимный том из этого. Этот анонимный том будет смонтирован на каждомRUNкоманда, предварительно заполненная содержимым изображения, а затем отбрасывается в конце
Comments