Как монтировать Тома хоста в контейнеры 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 ГБ данных дерева Portage были в любом из слоев после создания изображения. У вас могли бы быть хорошие компактные контейнеры, если бы не гигантское дерево portage, которое должно появиться в образе во время установки." Да, я могу использовать wget или curl для загрузки всего, что мне нужно, но тот факт, что просто соображение переносимости теперь заставляет меня загружать > 1GB дерева Portage каждый раз, когда я создание базового образа 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

путем вводить новые команды, коромысло направляет разрешить следующие случаи использования, которые тягостны с простым Докером:

  1. монтировать многоразовые Тома на этапе сборки, поэтому инструменты управления зависимостями могут использовать кэш между сборками.
  2. поделиться ключами ssh со сборкой (для вытягивания частных репозиториев и т. д.), не оставляя их в полученное изображение.
  3. сборка и запуск приложения в разных изображениях, возможность легко передавать артефакт с одного изображения на другое, в идеале иметь эту логику в одном файле Dockerfile.
  4. Tag / Push изображения прямо из Dockerfiles.
  5. передать переменные из команды сборки оболочки, чтобы их можно было заменить на Dockerfile.

и многое другое. Это самые важные проблемы, которые блокировали наше принятие Docker в Это дополнение не совместимо.


существует способ монтирования Тома во время сборки, но он не включает Dockerfiles.

техника будет создать контейнер из любой базы, которую вы хотели использовать (установка вашего Тома(ов) в контейнере с -v option), запустите сценарий оболочки, чтобы выполнить работу по созданию изображений, затем совершить контейнер как изображение, когда сделано.

не только это оставит лишние файлы, которые вы не хотите (это хорошо для безопасности файлы, а также, как 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.

другая соответствующая статья Оптимизация Изображений Docker | CenturyLink Labs, что объясняет, что если вы в конечном итоге загружаете материал во время сборки, вы можете избежать потери места в конечном изображении, загрузив, построив и удалив загрузку за один шаг.


это некрасиво, но я достиг подобия этого вот так:

Dockerfile:

FROM foo
COPY ./m2/ /root/.m2
RUN stuff

imageBuild.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 команда, предварительно заполненная содержимым изображения, а затем отброшенная в конце