Moby: Как объединить несколько изображений в один через Dockerfile

Созданный на 29 дек. 2013  ·  97Комментарии  ·  Источник: moby/moby

У меня есть несколько файлов Docker для создания образов, которые, например, настраивают клиент postgresql, настраивают общую среду приложения python.

Я хочу создать Dockerfile для моего веб-приложения на Python, которое объединяет оба этих изображения, а затем запускает еще несколько команд.

Если я правильно понял документацию, если я использую FROM во второй раз, я начну создавать новое изображение вместо добавления к текущему?

arebuilder kinfeature

Самый полезный комментарий

Я вижу, как это сделать, т.е. genericA --> specificA но есть ли способ сделать что-то вроде:

genericA --
            \
             ---> specificAB
            /
genericB --

?

Все 97 Комментарий

Вы их цепляете :)

так, например, если у вас есть один Dockerfile, который настраивает ваш общий клиент postgres и универсальное приложение python env, вы помечаете результат этой сборки (например, mygenericenv ), а затем ваши последующие Dockerfiles используют FROM mygenericenv .

например, для

## Dockerfile.genericwebapp might have FROM ubuntu
cat Dockerfile.genericwebapp | docker build -t genericwebapp -
## Dockerfile.genericpython-web would have FROM genericwebapp
cat Dockerfile.genericpython-web | docker build -t genericpython-web -
## and then this specific app i'm testing might have a docker file that containers FROM genericpython-web
docker build -t thisapp .

Я вижу, как это сделать, т.е. genericA --> specificA но есть ли способ сделать что-то вроде:

genericA --
            \
             ---> specificAB
            /
genericB --

?

Не с помощью официальных средств, но некоторым людям повезло вручную изменить иерархию изображений для достижения этой цели (но если вы делаете это, вы делаете это на свой страх и риск, и вы можете сохранить все части).

Причина, по которой это не будет официально поддерживаться, состоит в том, что я хочу взять "ubuntu" и перенести "centos" поверх. Будет много действительно забавных конфликтов, вызывающих кошмар поддержки, поэтому, если вы хотите делать такие вещи, вы сами по себе.

Хорошо, я понимаю, почему. Я искал составные блоки функциональности, но, возможно, это не вариант использования Docker ... похоже, я должен использовать его для настройки необработанных контейнеров, а затем запускать что-то вроде ansible или saltstack поверх, чтобы настроить в них программное обеспечение.

Идея контейнеров заключается в том, что самая маленькая единица реального состава - это контейнер. То есть контейнер - это наименьшее, что вы можете создать заранее, не зная, с чем еще он будет сочетаться, и у него есть надежные гарантии того, как он будет вести себя и взаимодействовать с другими компонентами.

Следовательно, любой блок, меньший, чем контейнер - будь то ruby ​​или сценарий оболочки, дерево исходных кодов C ++, отдельный двоичный файл, набор файлов конфигурации, системный пакет и т. Д. - не может быть безопасно скомпонован, потому что он будет вести себя очень по-разному, в зависимости от его зависимостей сборки, зависимостей времени выполнения и того, какие другие компоненты входят в состав.

Эта реальность может быть частично замаскирована грубой силой. Такая грубая сила может быть прагматичной и «достаточно хорошей» (гигантский Makefile, который автоматически определяет все для более переносимой сборки вашего приложения) или чрезмерно грандиозной («давайте заранее смоделируем каждую возможную перестановку каждой зависимости и интерференции между компонентами и выразим их в высокоуровневой абстракции! ")

Когда вы полагаетесь на Ansible, Chef или любое другое средство управления конфигурацией для создания «составных компонентов», вы полагаетесь на ненадежную абстракцию: эти компоненты фактически не могут быть составлены. От одной системы к другой они будут производить сборки, которые ведут себя по-разному миллионами способов. Вся эта лишняя абстракция в конце концов принесет вам очень мало.

Мой совет - сосредоточиться на двух вещах: 1) исходном коде и 2) исполняемом контейнере. Это единственные 2 надежных точки композиции.

Вск, 29 декабря 2013 г., 13:46, anentropic [email protected]
написал:

Хорошо, я понимаю, почему. Я искал составные блоки функциональности, но, возможно, это не вариант использования Docker ... похоже, я должен использовать его для настройки необработанных контейнеров, а затем запускать что-то вроде ansible или saltstack поверх, чтобы настроить в них программное обеспечение.

Ответьте на это письмо напрямую или просмотрите его на GitHub:
https://github.com/dotcloud/docker/issues/3378#issuecomment -31326172

Спасибо за то, что дали больше перспективы.

То есть вы говорите, что для повторного использования частей Dockerfiles доступен единственный инструмент - копирование и вставка? Если исходить из точки зрения скорее «разработчиков», чем «операторов», это кажется немного неправильным.

Возможно, наличие общедоступного индекса изображений - ошибка, создается впечатление, что вы можете делиться многократно используемыми строительными блоками, отдаленно аналогичными рецептам Chef, но мой опыт пока что это бесполезно, потому что:
а) для большинства изображений нет информации о том, что он делает и что внутри
б) документы поощряют внесение вашей работы в индекс (чтобы вы могли позже вытащить ее), даже если то, что вы сделали, вероятно, не будет полезно другим, я предполагаю, что большая часть того, что там, вероятно, не стоит делиться

Мне кажется, что в настоящий момент документация не поможет вам разумно использовать Docker.

@anentropic Правильный способ сделать это с Dockerfiles - создать несколько образов с несколькими Dockerfiles.
Вот пример: Dockerfile 1 создает общий образ поверх базового образа Ubuntu, Dockerfile 2 использует полученный образ Dockerfile 1 для создания образа для серверов баз данных, Dockerfile 3 использует образ сервера базы данных и настраивает его для специальной роли. .

docker build должно быть довольно легко запускать, и не следует добавлять ненужную сложность.

Публичный указатель изображений чрезвычайно полезен. Образы Docker обычно предназначены для запуска одной службы или группы служб, которые не могут работать в отдельных контейнерах. Обычно вы можете вытащить изображение, запустить его и установить и запустить какое-нибудь полезное программное обеспечение без особых усилий.

Понятно ... так что в сценарии, который я описал с помощью ascii выше, способ Docker будет выглядеть следующим образом:

  • начните с Dockerfiles для независимых образов GenericA и GenericB
  • чтобы создать изображение SpecificAB я бы скопировал и вставил содержимое файла GenericB Dockerfile в новый файл Docker, который начинается с: FROM GenericA

Проблема, которую я вижу, заключается в том, что если «рецепт» (заимствуя термин Chef) для GenericB довольно сложен и содержит много шагов, я не могу поделиться этой информацией, кроме как опубликовать Dockerfile _to Github_, поэтому чтобы другие могли _копировать и вставить_ соответствующие части в свой собственный Dockerfile.

Вы пробовали использовать публичный индекс? Например, я выполнил поиск по запросу "postgres" ... как мне судить о полезности (или каким-либо образом различать) таких изображений, как эти:

?

Какую ценность они обеспечивают, когда единственный способ убедиться, что у меня есть сервер Postgres, настроенный так, как я хочу, на конкретном базовом образе, без ничего хитрого, скрытого в нем, - это создать его сам с нуля.

Я могу увидеть ценность некоторых «официально одобренных» базовых изображений в публичном индексе. Я вижу ценность частного индекса моих собственных изображений, готовых к извлечению.

Но кажется позором, что нет возможности (кроме копирования и вставки) поделиться серией команд в Dockerfile в качестве рецепта ... например, предложение для команды 'include', которое было отклонено здесь https: // github .com / dotcloud / docker / pull / 2108.

@anentropic Вы можете использовать надежный образ, а также можете найти файл Dockerfile postgres для самостоятельного создания образа.

Образы обычно более полезны, когда вы настраиваете Dockerfile, чтобы они точно соответствовали вашим потребностям. Вот почему вы обнаружили, что большее количество пользователей загрузили образ для одного и того же программного обеспечения в реестр.

Существующие определенные изображения, такие как изображения postgres, могут не соответствовать вашим конкретным потребностям, но есть также базовые изображения, и их можно сразу использовать для создания чего-то полезного для вас.

Базовые изображения, такие как ubuntu , centos и некоторые изображения из stackbrew/* - это изображения, которые вы можете использовать для создания того, что вам нужно.

Пример отличного готового изображения - stackbrew/registry . Этот образ позволяет вам поиграть с частным реестром Docker, как только docker pull stackbrew/registry и docker run -p stackbrew/registry будут выполнены.

Цель Docker - помочь с развертыванием и подготовкой среды, в которой работает ваше программное обеспечение. Это означает, что сборки являются линейными и выполняются только во время начальной сборки, но вы будете запускать одно и то же программное обеспечение каждый раз.

Системы управления конфигурацией могут позволить вам сделать что-то большее или использовать некоторые другие уловки, но они не такие «неизменные», и вы можете получить два хоста, которые имеют тонкие различия, которые не улавливаются программным обеспечением для управления конфигурацией.

Ненавижу некро старую ветку, но хотел предложить что-то, что, ИМХО, помогает решить исходную проблему с плакатами и может помочь другим, ищущим аналогичное решение этой проблемы здесь.

Предположим для простоты, что все они используют одно и то же базовое изображение R . Представьте, что у меня есть услуга A и услуга B . Я хочу, чтобы они были в разных образах Docker и в одном образе Docker.

Напишите сценарий для установки службы A и напишите отдельный сценарий для установки службы B . Затем создайте репозиторий git со сценарием для A и еще один для сценария B . Создайте репозиторий git для всех трех образов Docker, которые будут созданы. Каждый из них содержит подмодули git со сценариями установки, которые будут использоваться. Каждый Dockerfile будет просто ADD сценарий установки, а затем RUN сценарий установки и сделает это для одного или обоих сценариев. Если вы хотите удалить скрипт (ы) из изображения, закрепите его после его запуска.

Таким образом, будет по одной копии каждого сценария установки и любых изображений докеров, которые вы хотите их использовать. Это позволяет избежать ненужного копирования кода и минимизировать затраты на обслуживание. Единственное дублирование усилий - продвижение фиксации, используемой подмодулями, что значительно лучше, чем альтернатива, и, вероятно, может быть автоматизировано.

Думаю, я неправильно понимаю, как это работает, поэтому отвечаю, чтобы получить разъяснения. Я хочу использовать Ubuntu 11 с официальными образами докеров Selenium. Они используют Ubuntu 15.

https://github.com/SeleniumHQ/docker-selenium/blob/master/Base/Dockerfile

Как я могу это сделать правильно? Чтобы клонировать это репо и отредактировать все файлы, чтобы сказать Ubuntu 11, а не 15? Это не может быть правдой, не так ли? Это означало бы, что каждый, кто не согласен с каким-либо аспектом официальных изображений, не может использовать их без дублирования кода для них. Я думаю, что ошибаюсь, может кто-нибудь объяснить? Как правильно использовать официальный образ селена с Ubuntu 11?

@rjurney да, вот как это сработает; в вашем примере весь Dockerfile разработан с учетом ubuntu: 15.04 ; доступны ли эти пакеты в ubuntu: 11? Они работают? На них работает селен? Скорее всего, в Dockerfile необходимо внести изменения, чтобы он работал с другой версией Ubuntu.

«замена» базового образа существующего образа также не сработает, потому что Docker сохраняет только _различия_ между базовым образом и образом. Следовательно, использование другого базового изображения приводит к непредсказуемым результатам (например, «удалить файл X», где «файл X» существует в исходном базовом изображении, но не в выбранном вами базовом изображении). Кроме того, пакеты / двоичные файлы в образах, построенные «поверх» базовых образов, представляют собой пакеты, созданные для _этой_ версии, эти двоичные файлы могут быть несовместимы с другим базовым образом.

Это будет означать, что каждый, кто не согласен с каким-либо аспектом официальных изображений, не может использовать их без дублирования кода для них.

да. Официальные образы поддерживаются разработчиками этих образов (которые в данном случае являются разработчиками Selenium). Если вы считаете, что в эти изображения необходимы изменения, лучше всего открыть запрос функции в их репозитории. Если этот запрос функции не принят, вам, вероятно, следует создать свою собственную версию.

(Также обратите внимание, что нет официального изображения ubuntu:11 )

В остальном мире программного обеспечения одинарное наследование не рассматривается как
адекватно выражать необходимую семантику. Это приводит к большому количеству кода
дублирование, которое будет считаться ошибкой. Почему это рассматривается как
приемлемо для докера? Даже если вы создаете одну службу за раз,
состав нужен на уровне операционной системы. Я не хочу бить
мертвая лошадь, но этот предел кажется немного экстремальным. Может быть лучше
выражается как лучшая практика? В результате строгости этого
решение, кто-то создаст инструмент, который выполняет композицию или несколько
наследования и выражает их через единичное наследование и дублирование.
То, что это находится за пределами докера, не будет служить сообществу докеров.

В среду, 9 декабря 2015 г., Себастьян ван Стейн <
[email protected]> написал:

@rjurney https://github.com/rjurney да, вот как это сработает; в
ваш пример, весь Dockerfile разработан с учетом ubuntu: 15.04 ;
доступны ли эти пакеты в ubuntu: 11? Они работают? Бегает ли селен
на них? Скорее всего, необходимо внести изменения в файл Dockerfile.
чтобы он работал на другой версии Ubuntu.

"замена" базового изображения существующего изображения также не сработает, потому что
Docker сохраняет только _различия_ между базовым образом и
изображение. Следовательно, использование другого базового изображения приводит к непредсказуемым
результаты (например, «удалить файл X», где «файл X» существует в исходной базе
изображение, но не в выбранном вами базовом изображении). Также пакеты / двоичные файлы
в образах, построенных "поверх" базовых образов, это пакеты, которые создаются
для _этой_ версии эти двоичные файлы могут быть несовместимы с другими
базовое изображение.

Это означало бы, что каждый, кто не согласен с каким-либо аспектом
официальные изображения не могут использовать их без дублирования кода для них

да. Официальные изображения поддерживаются разработчиками этих изображений.
(которые в данном случае являются разработчиками Selenium). Если вы думаете, что изменится
необходимы для этих изображений, лучше всего открыть запрос функции в
их хранилище. Если этот запрос функции не принят, вам следует
возможно создайте свою собственную версию.

(Также обратите внимание, что нет официального изображения ubuntu: 11)

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/docker/issues/3378#issuecomment -163188299.

Рассел Джурни twitter.com/rjurney russell. [email protected] relato.io

Множественное наследование

12749 был последней попыткой добавить такую ​​функциональность - в конечном итоге она была отклонена, потому что в первую очередь нужно проделать другую работу.

Над компоновщиком ведется большая работа, в том числе включение клиентских сборок, которые могут немного открыть это.

Dockerfiles с одинарным наследованием работает для (подавляющего) большинства случаев использования, поэтому нет необходимости спешить с его улучшением. Делать это нужно правильно и осознанно.
И, основываясь на ваших комментариях выше, я бы сказал, что вам действительно не нужно множественное наследование, просто способ указать базовый образ, с которым запускается Dockerfile, без дублирования существующего кода.

Да, это удовлетворило бы мои потребности. Возможность изменять некоторые свойства
цепочка докер-файлов.

Хорошо, рад слышать, что ты в курсе. Спасибо за терпеливость :)

В среду, 9 декабря 2015 г., в 9:59 Брайан Гофф [email protected] написал:

@rjurney https://github.com/rjurney множественное наследование также
чрезвычайно сложный, а не то, что вы просто добавляете, не задумываясь
для последствий, крайних случаев и несовместимости.

12749 https://github.com/docker/docker/pull/12749 был последним

попытка добавить такую ​​функциональность - в конечном итоге отклонена, потому что есть
другие работы, которые необходимо выполнить в первую очередь.
Над компоновщиком много работы, включая включение
клиентские сборки, которые могут немного открыть это.

Dockerfiles с единичным наследованием работает в (подавляющем) большинстве случаев использования,
поэтому не стоит спешить с этим. Это нужно делать правильно и
умышленно.
И, основываясь на ваших комментариях выше, я бы сказал, что вам действительно не нужно несколько
наследование, просто способ указать базовый образ, который запускается Dockerfile
против без дублирования существующего кода.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/docker/issues/3378#issuecomment -163340165.

Рассел Джурни twitter.com/rjurney russell. [email protected] relato.io

@rjurney Откуда вы

На мой взгляд, докеру нужна не концепция множественного наследования, а концепция включения или внешних зависимостей. например, вы можете монтировать контейнеры во время выполнения. Что действительно необходимо, так это способ создания эквивалента с изображениями. Таким образом, вы могли, например, иметь образ, который был определен как основанный на Fedora 22, и смонтировать образ оракула для добавления функциональности базы данных.

Это можно сделать довольно успешно при запуске контейнеров, но просто нет синтаксиса для указания этого с изображениями. Так что до времени выполнения докер не сможет узнать об этих зависимостях или каким-либо образом управлять ими за вас.

Обратите внимание, что я упомянул множественное наследование и композицию.
Композиция, безусловно, является предпочтительным способом сделать это.

Я согласен со всем остальным, что вы сказали, так что +1.

В среду, 9 декабря 2015 г., Билл Си Римерс [email protected]
написал:

@rjurney https://github.com/rjurney Откуда вы берете информацию.
Насколько мне известно, в Java никогда не было множественного наследования и никогда не будет.
Я уверен, что то же самое верно и для многих языков. Многие считают несколько
наследование крайне вредно, так как может привести к тому, что почти невозможно
предсказуемый код. То же самое можно сказать и о докер-контейнере.

На мой взгляд, докеру нужна не концепция нескольких
наследование, но концепция включаемых или внешних зависимостей. например
Вы можете монтировать контейнеры во время выполнения. Что действительно необходимо, так это способ
эквивалент с изображениями. Таким образом, вы могли бы, например, получить изображение, которое
был определен как основанный на Fedora 22, и смонтировать образ оракула для добавления
функциональность базы данных.

Это можно сделать довольно успешно при запуске контейнеров, но есть
просто нет синтаксиса для указания его с изображениями. Так что до времени выполнения нет
способ, которым докер может узнать об этих зависимостях или каким-либо образом управлять ими для
ты.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/docker/issues/3378#issuecomment -163351035.

Рассел Джурни twitter.com/rjurney russell. [email protected] relato.io

Я собираюсь заткнуться после этого, но я по ошибке поместил эту тираду в вышеупомянутый запрос на перенос вместо этого тикета. Я помещаю это сюда.

Кто-то собирается это построить. Непринятие запроса с добавлением INCLUDE приведет к задержке и экстернализации этой функции. Это должно быть основанием для решения здесь: должно ли это быть внутри докера или вне докера?

На ум приходит пример. В Apache Pig команда приняла решение не включать циклы, несмотря на множество запросов на них, потому что было решено, что Pig должен отлично подходить для потоков данных DAG, и на этом все. Вместо этого была создана интеграция со скриптами Pig, так что вы могли циклически просматривать скрипты с любого языка JVM. Обратите внимание, что это было осознанное решение, и были рассмотрены альтернативы. На мой взгляд, это модельный процесс.

На ум приходит еще один пример со Свинью ... Макросы Свиньи. Они не существовали и не были свиньями, пока кто-то (хорошо, я) не начал обсуждать, насколько ужасно уродливым был их большой проект свиней и что не было способа исправить эту проблему, не создавая Pig из внешнего инструмента, который был нежелательно. Многие вмешались, и команда Pig добавила макросы. Макросы делают чистую свинью возможной, и это приносит пользу сообществу.

Я предлагаю вам сразу обсудить это решение и обсудить его, чего здесь еще не было, и для поиска, вероятно, здесь и должно быть. Это будет существовать. Дублирование скриптов на предметных языках - это ужасно. Народ потребует этого. Будет ли эта функция внутри Docker или вне Docker? Как вы будете способствовать такому поведению вне докера?

Извините, мне, вероятно, не хватает большого количества контекста в списке рассылки, но как новый пользователь Docker ... я очень не решаюсь делать что-то с Docker без возможности составлять файлы докеров из существующих рецептов. Я пошел по этой дороге со Свиньей, и это чуть не убило меня. Думаю, многие люди так почувствуют.

На случай, если кому-то наплевать ...

Наполовину принятая презентация о циклах и макросах в Pig: http://wiki.apache.org/pig/TuringCompletePig
Макрос свиньи JIRA: https://issues.apache.org/jira/browse/PIG-1793
Интерфейс API для Pig JIRA: https://issues.apache.org/jira/browse/PIG-1333
Тот, который был категорически отклонен, чтобы уважать Apache Hive ... добавить SQL в Pig: https://issues.apache.org/jira/browse/PIG-824

Наконец, у меня появилась идея, которая может упростить это изменение ... что, если файлы INCLUDE'd не могут наследоваться? т.е. вы избежите возражений, сделав все очень простым. С остальным разберитесь позже, когда вы узнаете больше. Например, может быть простой файл Dockerfile, который устанавливает предварительные требования и двоичные файлы, а также настраивает демонов для MySQL в Ubuntu. Если необходимо, это может быть версией Ubuntu и MySQL. Лично я собираюсь взломать утилиту для выполнения этих простых операций INCLUDE и использовать ее для такой организации своих файлов докеров. Я не могу дождаться, чтобы заказать и повторно использовать свой код.

+1 за идею ВКЛЮЧИТЬ. Хотя я считаю, что запрет наследования только решит проблему, поскольку теперь вы сможете изменять основной образ, от которого наследуете, но не другие изображения, которые вы включаете. В принципе, что имело бы смысл, если бы вы могли указать изображение как «включаемое», так как оно не доставляет никаких вещей операционной системы, которые могут нарушить существующий материал базового образа. Этот флаг должен быть установлен в процессе сборки докера и предотвратит включение неадекватно помеченных изображений. И я имею в виду, давайте посмотрим правде в глаза. Если вы играете с Dockerfiles, вы, вероятно, не тот человек, который видит свою машину в первый день, поэтому я считаю, что, хотя имеет смысл не допустить, чтобы конечный пользователь Docker делал глупые вещи, должно быть немного больше свобода для парней, которые создают эти образы. Я имею в виду серьезно, возможность выбрать базовый образ и включить в него все, что я хочу, чтобы подготовить свое приложение, было бы чертовски круто.

+1 за ВКЛЮЧИТЬ. Мне просто нужно объединить образ nginx и ssh в один. Почему это должно быть так сложно?

Мысль о том, что в этом нет необходимости, откровенно сбивает с толку до такой степени, что
лукавый. Большинство пользователей будут использовать это, если оно будет создано. "Добавить ssh в
ubuntu "и" добавить nginx в ubuntu "- довольно распространенные задачи, которые каждый
не нужно повторять. Docker HQ действительно говорит по этому поводу следующее:
«Очевидно, это необходимо, но мы думаем, что это будет слишком некрасиво. Так что мы притворяемся». Это
было бы лучше, если бы вы действительно могли быть честны и откровенны в этом вопросе.
Извини, если я капризничаю.

В субботу, 23 января 2016 г., в 18:22 Vazy [email protected] написал:

+1 за ВКЛЮЧИТЬ. Мне просто нужно объединить образ nginx и ssh в один. Почему
это должно быть так сложно?

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/docker/issues/3378#issuecomment -174243875.

Рассел Джурни twitter.com/rjurney russell. [email protected] relato.io

@rjurney , подождем выхода сборки; потому что в этом случае будет несколько способов создания образов (и, следовательно, может появиться настраиваемый конструктор, который это делает). Одна из причин, по которой специалисты по сопровождению докеров (работающие или не работающие на Docker) резво относятся к этому, заключается в том, что это добавит сложности там, где мы хотим добавить гибкости и простоты. Распаковав построитель, мы получим лучшее разделение задач (между построением образов и их запуском), а многие варианты использования будут более свободно реализованы в пользовательских построителях.

Опять же, вы выталкиваете это из проекта? Пользовательские звуки ... нет
по умолчанию, включен способ. На самом деле включает в себя простую потребность, которая
почти у всех есть. Повторение - сложность. Только наследование
сложность. Включает соответствие потребности каждого человека самым простым способом
возможный.

В воскресенье, 24 января 2016 г., Винсент Демейстер [email protected]
написал:

@rjurney https://github.com/rjurney подождем выхода сборки;
потому что в этом случае будет несколько способов создания образов (и, следовательно,
может появиться пользовательский конструктор, который это сделает). Одна из причин докера
Сопровождающие (работающие или не работающие на Docker) резвятся об этом,
потому что это добавит сложности там, где мы хотим добавить гибкости и
простота. Распаковав конструктор, мы получим лучшее разделение
беспокойство (между созданием образов и их запуском) и множество вариантов использования
будет более свободно реализовываться в пользовательских конструкторах.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/docker/issues/3378#issuecomment -174423973.

Рассел Джурни twitter.com/rjurney russell. [email protected] relato.io

+1, объединение изображений было бы чрезвычайно полезно. Представьте (не дай бог) вариант использования C ++. Я создаю образ с ускорением, другой с Qt, все с одним и тем же компилятором и т. Д. Теперь, скажем, я хочу создать приложение с ускорением и Qt, мне просто нужно объединить два и presto - среда разработки готова. Это было бы невероятно полезно.

Лично я считаю, что это слишком важный вопрос, чтобы не заниматься. При этом нам нужно хорошо понимать, каковы проблемы и масштабы, независимо от того, где это реализовано.

Итак, я вижу эти проблемы, возникающие в результате слияния.

  1. Обработка конфликтов слияния.
  2. Разрешение разных баз (Ubuntu и CentOS).

На первый, я думаю, простой ответ - нет. На мой взгляд, это звучит слишком сложно и потенциально проблематично, и для решения потребуется набор инструментов, но все же может быть слишком волшебным. Итак, если это было добавлено, конфликты слияния просто не удались. Я полагаю, что к этому можно было бы вернуться позже, но это похоже на больше проблем, чем оно того стоит.

Что касается второго случая, похоже, вы могли бы добавить ограничение, что они разделяют некоторые базовые слои. Теперь возникает вопрос, сколько достаточно. Я думаю, что правильным ответом при запуске будет то, что два объединяемых изображения должны иметь одно и то же изображение FROM . Здесь может потребоваться больше ограничений, но мне не ясно, не подпадет ли этот случай под проблему 1, которую можно решить, просто запретив ее.

Есть ли еще какие-то проблемы, которых мне здесь не хватает?

Я думаю, не должно быть попыток слияния ... Я не вижу, чтобы это происходило

Более реалистичным подходом может быть шаблонное решение, то есть разрешить INCLUDE Dockerfile _fragment_ (в котором нет предложения FROM , только список команд) в настоящий Dockerfile ... фрагменты можно совместно использовать, повторно использовать и включать в любой совместимый файл Dockerfile базового образа.

Я новичок в Docker и скромно учусь. Но я думал, что основная цель Docker - создавать очень маленькие _reusable_ приложения, чтобы позже объединить их любым способом в отличные большие конечные приложения, как в веб-приложении. Если это так, ИМХО, выражение типа INCLUDE является обязательным.

@jmcejuela во многих случаях «повторное использование» - это создание изображений, предназначенных для определенной службы, и объединение этих изображений / контейнеров для формирования вашего приложения. Отдельные компоненты вашего приложения можно использовать повторно (возможно, отличается только конфигурация контейнера), но то, как вы их комбинируете, формирует реальное приложение.

@thaJeztah Я понимаю, спасибо.

Но делая его конкретным, как люди, опубликованные ранее, скажем, я создаю веб-приложение, которое запускает приложение scala (изображение A ), затем создаю веб-сервер с помощью nginx (изображение B ), а затем использую ssh (изображение C ) и требуется дополнительное приложение Python (изображение D ). Скажем, я создал по 4 Dockerfile для каждого. Как мне объединить их с Docker, чтобы создать мое окончательное веб-приложение (изображение E ?)

Мне просто нужен простой способ сделать это. Меня не волнуют философские споры о множественном наследовании, включать или нет, составлять или нет и т. Д. Хотя, конечно, я бы не хотел копировать и вставлять, как было предложено ранее.

Большое вам спасибо за ваше время. Я все еще изучаю Docker.

@jmcejuela, вы бы не объединяли _images_, вы бы запускали их как отдельные контейнеры и заставляли их взаимодействовать для формирования приложения. Вы можете сделать это с помощью Docker Compose, который позволяет вам определять свой «стек». Например, см. Https://github.com/docker/example-voting-app/blob/master/docker-compose.yml (и README; https://github.com/docker/example-voting-app/ blob / master / README.md)

Что касается части «ssh», это действительно зависит от того, для чего вы хотите ее использовать; в целом, контейнеры считаются "неизменяемыми", поэтому вы не будете использовать ssh в контейнер и изменять его, а создадите новый контейнер, чтобы заменить старый; данные, которые должны сохраняться за пределами жизненного цикла контейнера, затем сохраняются в томе, чтобы новый контейнер мог использовать эти файлы.

@jmcejuela Конструктор Docker принимает содержимое Dockerfile на STDIN, так что его можно «относительно» легко сгенерировать? Если необходимо передать контекст, то все должно быть заархивировано и загружено в docker build . По моему опыту, это самый простой способ получить композицию.

Я разрабатываю (и играю с ним) подход, основанный на вышеупомянутой концепции. Приложение nodejs подготавливает файл TAR в памяти (с Dockerfile и добавленными файлами) и выгружает его в STDOUT. STDOUT передается по конвейеру в docker build . Составные части проверяются на версии, тестируются и выпускаются как модули NPM. Я привел очень короткий пример, демонстрирующий тестовое изображение для crond - http://pastebin.com/UqJYvxUR

Спасибо @thaJeztah. В конце концов, мне нужен только один файл, который мои со-разработчики могут запустить, чтобы иметь весь стек разработчика, а затем иметь возможность запускать его и на продукте, если это необходимо. Я более подробно рассмотрю docker compose.

Кроме того, INCLUDE был предложен давно (https://github.com/docker/docker/issues/735).

@jmcejuela Дело в том, что большинство пользователей

Только если вы делаете это неправильно, команда docker exec существует уже довольно давно, и мне никогда не понадобился ssh с тех пор ...

@anentropic Это справедливо только в том случае, если вы развертываете простые службы без зависимостей. Если у вас есть сложная цепочка зависимостей для какой-либо службы, например, всего, что связано с машинным обучением, вы будете дублировать код для развертывания служб. И нет веских причин, по которым вы должны это делать. Тот факт, что docker - это язык, специфичный для предметной области, не означает, что большая часть знаний о языках программирования будет выброшена за дверь, и ни один из старых уроков не применим. Здравомыслие по-прежнему имеет значение. Копирование и вставка рецептов - безумие.

Это также справедливо только в том случае, если вы подписываетесь на мировоззрение «единой службы», которое распространяется не на всех пользователей докеров.

@anentropic Согласно дорожной карте Docker, запуск контейнеров через docker exec может быть (приходит) в равной степени неправильным.

PS Движок rkt достиг

@rjurney,: 100:

Множественное наследование, любимое или ненавистное, - сложная черта, которая, несомненно, вызовет сопротивление. Include превращает файлы Dockerfiles из рецепта сборки в язык с проблемами пути, которые сложно решить.

Что, если мы посмотрим на проблему по-другому. Что, если бы мы могли « ADD / COPY » выбрать файлы из другого образа докера в создаваемый. Таким образом можно получить выгоду от повторного использования функциональности и избежать дублирования кода. Поскольку мы не используем FROM несколько раз в изображении, а просто копируем двоичные файлы явным образом, это должно вести себя четко определенным образом, а когда это не так, это означает сбой. Учитывая, что это работает с образами докеров и может использовать реестры в качестве решения, а не какой-то новый путь поиска, я надеюсь, что это разумное предложение. Дополнительным бонусом является то, что нам также не нужно повторно запускать один и тот же код несколько раз. Кроме того, хотелось бы надеяться, что можно избежать серьезных изменений в строителе. Мысли?

Может быть, это предложено где-нибудь в другом месте, и в этом случае было бы неплохо дать ссылку.

Привет,
Какое бы решение ни было выбрано, подготовка изображения из нескольких независимых источников - это то, что я был очень удивлен, что невозможно.
Мне бы хотелось пропустить подготовку образа, поскольку во время выполнения мы можем выполнить этот процесс, чтобы во время выполнения был развернут набор образов, и не нужно было переделывать образ каждый раз, когда изменяется зависимость.
Я искал альтернативы, но пока не нашел подходящих, это серьезный пробел в использовании.
Выглядит довольно легко выполнить с помощью ACI.
Спасибо!

: +1: хотелось бы найти решение этой проблемы и рада, что об этом хотя бы говорят. Даже если для этого требуются одинаковые базовые изображения.

Оказывается, копирование с других изображений предлагается в другом месте. Это проблема (https://github.com/docker/docker/issues/18596).

спасибо @jakirkham ..

+1 для функции множественного наследования докеров

РЕДАКТИРОВАТЬ:

См. Также: https://github.com/docker/docker/issues/13026

Я думаю, что проблема, с которой вы столкнулись, заключается в том, что неумение составлять рецепты не имеет смысла. Docker compose отлично подходит для использования нескольких контейнеров в приложении. Docker swarm отлично подходит для работы с несколькими узлами. Но во многих случаях нет возможности включить чужую работу на уровне исходного кода. Вы должны наследовать один раз или воссоздать его, что является ограничивающим фактором.

Пт, 18 марта 2016 г., в 9:01, Элвин Шеволло < [email protected]

написал:

Ответ @thaJeztah https://github.com/thaJeztah очень
поучительно. Я новичок в Docker и не понимаю, почему вы не можете комбинировать
несколько _images_ вместе, но Docker Compose кажется решением
объединение нескольких контейнеров в одно приложение, которое я искал
за.

Думаю, проблема для меня в том, что я сначала думал, что понял Docker
но теперь выясняю, что я этого не делаю. Я собираюсь вернуться и сделать еще немного
чтение!

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/docker/issues/3378#issuecomment -198426036

Рассел Джурни twitter.com/rjurney russell. [email protected] relato.io

@rjurney Да, посмотрев еще немного на Docker Compose, вы правы, это как раз мое замешательство. Например, есть изображение PHP и изображение Centos, но нет наследования между разными изображениями, так что это вроде все или ничего. В официальном образе PHP используется debian:jessie но я хочу, чтобы моя установка была основана на Centos, поэтому кажется, что если я хочу использовать конкретное изображение, я должен принять остальную часть установки или скопировать и вставить исходный файл Dockerfile. и скатать свое собственное изображение с нуля, похоже, нет золотой середины, где я мог бы смешивать и сопоставлять изображения.

РЕДАКТИРОВАТЬ:
Просто чтобы прояснить, я понимаю, почему вы не можете смешивать образы на основе Ubuntu и Centos вместе, но я не понимаю, почему у вас не может быть какой-то иерархической структуры. Тогда вместо загрузки всего изображения вы просто загрузите изменения с одного изображения на другое.

INCLUDE мне тоже было бы безумно полезно. Без него мне осталось копипасту.

@RomanSaveljev Я не понимаю:

Согласно дорожной карте Docker, запуск контейнеров через docker exec может быть (приходит) в равной степени неправильным.

Это не говорит о том, что docker exec устареет. docker exec всегда был инструментом отладки, как и SSH в контейнере Docker.

Я чувствую себя глупо, участвуя в этом, но какого черта ... Я предлагаю еще раз:

Почему бы нам не упростить проблему и не начать с реализации INCLUDE, чтобы не допускать наследования? Другими словами, вы можете включать только файлы, у которых нет FROM.

Это позволит справиться со многими вариантами использования, и будет толчок к файлам, которые люди ВКЛЮЧАЮТ, для работы в любой разумной операционной системе. uname существует не просто так. Это будет первым шагом, и отзывы об этой реализации помогут определить что-нибудь еще.

Это кажется легким решением. Это не было бы тонной работы. Это не будет сложно. Правильно?

@rjurney, это в основном то, что делает https://github.com/docker/docker/pull/12749

@rjurney : Не

  1. Как совместить несколько самостоятельных работ?
  2. Как эффективно хранить такие сборники?
  3. Как объединить несколько частей работы на двоичном уровне, а не на уровне сборки?

Вероятно, в этот список можно было бы добавить больше элементов. Решение INCLUDE обрабатывает первый пункт маркера. Как только это будет сделано, это станет стандартной структурой, в которой эффективность двоичного хранилища может быть прозрачно повышена для конечного пользователя. Как только это будет сделано, имеет смысл поговорить об инструментах, которые делают те же манипуляции напрямую с файлами изображений. Однако этот последний шаг, конечно, очень сомнительный. Как только вы делаете это непосредственно с файлами изображений, существует огромная вероятность того, что в конечном итоге изображение окажется неработоспособным. Однако, если предположить, что только опытные пользователи (те, кто точно знает, что они делают) будут делать третий вариант, это мне не кажется необоснованным добавлением ... в конечном итоге.

Для тех, кто хочет что-то действительно компонуемое таким образом, вы можете взглянуть на Nix (NixOS, дистрибутив Linux и система управления пакетами). Это просто требует, чтобы вы переупаковали все свое программное обеспечение, обычно собираемое из исходных текстов, и отказались от всего, что, как вы думали, вы знали о Linux;). Это хорошая система, но она требует много работы, учитывая, что ею пользуются не многие люди, но я искренне надеюсь, что она приживется.

Как уже говорили другие, компонуемость Docker - это скорее создание на уровне обслуживания.

: +1: defo стоит подумать о компонуемой модели - было бы замечательно, если бы вы могли импортировать поведения в файл докеров. например, у меня сейчас есть вариант использования, когда я хочу включить apache thrift в ряд очень разных контейнеров сборки на основе Alpine linux - некоторые будут создавать службы Java, другие PHP и другие Node.

Было бы хорошо иметь возможность включать экономичную установку, а не копирование и вставку - я думаю, что я могу достаточно легко извлечь в сценарий оболочки и ДОБАВИТЬ и ЗАПУСТИТЬ его.

Итак, как мне использовать изображения ruby-2.3 и java-8? Они используют тот же образ debian jessie, что и базовый (я читал файлы dockerfiles). Я просто хочу выполнить команды, присутствующие в них обоих. В нынешнем виде мне пришлось скопировать / вставить Java Dockerfile в Ruby Dockerfile. Приложению нужны и то, и другое, я никак не могу обойти это стороной.

Я воспользовался возможностью, чтобы удалить некоторые команды Dockerfile, пока вставлял их - они не были вредными, а просто излишними, поскольку «базовый» Dockerfile (в который я вставлял команды) уже выполнил эти шаги. Таким образом, я могу видеть аргумент, что мне на самом деле не нужны изображения "ruby" и "java", я фактически создавал 3-е изображение "ruby + java all-in-one".

Однако в этом конкретном случае команды в этих двух изображениях кажутся полностью совместимыми - если бы я просто объединил их, они должны были бы работать. Было бы полезно указать такие обстоятельства. Я не большой поклонник подхода копирования / вставки - в моем случае файлы Dockerfiles Java и Ruby были достаточно простыми, но некоторые файлы Dockerfiles намного сложнее.

Однако для всех, кто хочет эту функцию, вроде меня - я вижу множество ситуаций, когда это было бы проблематично. Таким образом, это не просто вопрос предоставления возможности запускать «nginx», а затем «ssh» на одном и том же образе докера - та же функциональность также позволит вам запускать «debian» и «centos», что определенно не приведет к работоспособное изображение. Если он когда-либо будет представлен, похоже, что это должен быть экспериментальный вариант, отключенный по умолчанию, к которому прилагается множество предупреждений.

Таким образом, каким бы ни был интерфейс этой функции, он должен четко указать, что ответственность за правильное получение повторно используемых поведений (наборов команд) лежит на разработчике Dockerfile.

РЕДАКТИРОВАТЬ: Ах, я пропустил обсуждение ВКЛЮЧИТЬ.

Почему бы нам не упростить проблему и не начать с реализации INCLUDE, чтобы не допускать наследования? Другими словами, вы можете включать только файлы, у которых нет FROM.

Это позволит справиться со многими вариантами использования, и будет толчок к файлам, которые люди ВКЛЮЧАЮТ, для работы в любой разумной операционной системе. uname существует не просто так. Это будет первым шагом, и отзывы об этой реализации помогут определить что-нибудь еще.

Это кажется легким решением. Это не было бы тонной работы. Это не будет сложно. Правильно?

: +1:

@rjurney это в основном то, что делает # 12749

: +1: отлично, с нетерпением жду возможности увидеть то, что он сможет сделать в окончательном виде.

Очень интересует эта концепция тоже. Механизм «ВКЛЮЧИТЬ» - очень грубое решение, но, честно говоря, он представляет собой довольно большой шаг вперед в ремонтопригодности набора файлов докеров.

Лично я бы не хотел, чтобы он _fail_ при обнаружении FROM , я бы хотел, чтобы он _игнорировал_ FROM и просто последовательно применял остальные команды.

То, что этого еще не произошло без поддержки FROM, является открытым исходным кодом
пародия.

В чт, 19 января 2017 г., в 10:19, Кен Вильямс [email protected]
написал:

Очень интересует эта концепция тоже. Механизм «ВКЛЮЧИТЬ» - это очень
грубое решение, но, честно говоря, это будет довольно большой шаг вперед в
ремонтопригодность набора докер-файлов.

Лично я бы не хотел, чтобы он терпел неудачу при обнаружении FROM, я бы
хотите, чтобы он игнорировал FROM и просто применял остальные команды в
последовательность.

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/docker/docker/issues/3378#issuecomment-273854850 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AACkpS8-EQ7r0BHid75rxeBDhOUDFRXlks5rT6kXgaJpZM4BWkJ9
.

-
Рассел Джурни twitter.com/rjurney russell. [email protected] relato.io

Вот в чем дело, мне не обязательно слияние. Я думаю, что многие проблемы можно решить с помощью ребаза. Мой обычный вариант использования

A (ubuntu) -> B (например, nginx)
A (ubuntu) -> C (например, узел)

И я хочу комбинированное изображение B&C. Обычно они не имеют ничего общего друг с другом, поэтому достаточно просто переназначить все различия между A и C на B.

А -> В -> С '

Кажется, эту проблему решить проще.

@cloutiertyler Обычно приложениям Node.js эта функция не требуется для работы с Nginx (на мой взгляд). Docker - это два контейнера, один для Nginx, другой для Node. Мы настраиваем контейнер Node так, чтобы его порт был открыт только для контейнера Nginx, и позволяем контейнеру Nginx прослушивать общедоступный порт (например, 80). Есть ли причина, по которой Nginx должен находиться в том же контейнере, что и Node?

Пример файла Docker Compose может быть

version: "2.1"

services:
  app: # Node.js application image
    build: .
  nginx: # Nginx container who can make request to app container
    image: nginx:1.10-alpine
    depends_on:
      - app
    ports:
      - "${PORT:-8080}:80" # public port, you may want PORT=80

@franklinyu Я ценю ответ. На самом деле я просто использовал в качестве примера две случайные службы. Мой обычный вариант использования будет начинаться с общей службы (например, узла, основанного на ubuntu) и моего собственного образа (также основанного на ubuntu) и желая объединить их.

Кстати, это не совсем перебазирование, но открывает множество вариантов использования Dockerfiles.
Dockerfile теперь поддерживает многоэтапные сборки. Пример:

FROM golang AS myapp
COPY . /myapp
RUN cd /myapp && go build

FROM scratch
COPY --from=myapp /myapp /usr/bin/myapp

Вы можете иметь столько этапов, сколько захотите.
Параметр --from основном переключает контекст на указанное имя цели сборки.
Когда вы docker build -t myapp . , результирующее изображение с именем myapp:latest будет из последнего этапа.
Вы также можете построить определенные этапы, например, с помощью docker build --target=myapp .

В версии 17.05 (в настоящее время доступно как RC1) есть еще несколько очень хороших улучшений Dockerfile, попробуйте!

Вот это интересно! Я не знал, что ты сможешь это сделать. Мне придется попробовать, чтобы увидеть, решает ли он мои распространенные варианты использования.

Хотя это отличная функция, после того, как я попробовал ее, она не решила мою самую распространенную проблему. Я только что снова столкнулся с этим сегодня.

Мне нужен образ Jenkins с установленным Docker, чтобы я мог создавать из контейнера. Дело в том, что это невозможно сделать без репликации процесса установки того или другого в моем Dockerfile.

Это тот случай, когда зашоренные аргументы о том, что в этом нет необходимости, поскольку каждый контейнер должен быть только одной службой, очевидно, неприменимы. Моя «одна услуга» сочетает в себе функциональность Docker и Jenkins.

Дело в том, что это невозможно сделать без репликации процесса установки того или другого в моем Dockerfile.

Итак, вы хотите разбить два файла докеров в один, чтобы вам не приходилось копировать / вставлять что-то?

Копирование / вставка в этом случае эквивалентно разветвлению. Что я хочу сделать, так это избежать разветвления файла Docker, чтобы не пропустить исправления ошибок / безопасности или другие изменения, когда они неизменно меняются позже.

Не могу просто пройти мимо. Ищете способ распределить изменения по длинной цепочке наследования изображений (глубже 2). Многоступенчатость, похоже, не та вещь, которая проясняет проблему. Наличие объекта, который может содержать только блок директив, что позволяет мне включать его во все мои образы-наследники вместе с функциональностью базового образа, выглядит как рациональная эволюция.

Тем, кто задается вопросом, как это сделать с точки зрения Docker, уделите несколько минут обзору:
https://github.com/floydhub/dockerfiles

Здесь он создает целое дерево Dockerfiles. По мере того, как вы спускаетесь по дереву, вы обнаруживаете различные комбинации зависимостей, каждая ОТ уровня выше в дереве. Итак, если вы последовали за деревом из
-ubuntu->common-deps->python3->deepLearningBase->pyTorch
и ты очень хотел

-ubuntu->common-deps->python3->deepLearningBase->pyTorch 
+
-ubuntu->common-deps->python3->deepLearningBase->TensorFlow 

Все, что вам нужно сделать, это добавить узел (папку) в deepLearningBase для обоих, например
-ubuntu->common-deps->python3->deepLearningBase->TensorFlow-pyTorch

Теперь вам все еще нужно создать файл докеров, который объединяет файлы докеров pyTorch и TensorFlow, но
Ключевым моментом является то, что эти файлы будут ОЧЕНЬ ПРОСТОЙ, всего пара строк установки поверх deepLearningBase.

Итак, что действительно необходимо, так это несколько репозиториев github большего размера, подобных этому, для разных «миров», таких как веб-разработка, глубокое обучение, встроенное программное обеспечение и т. Д.

Затем вы просто следуете дереву до требуемой сборки, и, если еще никто не сделал ее, просто добавьте узел и объедините 2 или 3 строки apt-get и создайте новую среду.

Это похоже на стиль композиции «выбери свое собственное приключение». ВКЛЮЧИТЬ было бы намного проще. Черт, я просто хочу скомпоновать указанное изображение gcc с nano чтобы мне не приходилось каждый раз устанавливать nano из apt-get!

Я согласен с @chambm в его комментарии выше. Нет никаких причин, по которым это не должно быть возможным в большинстве случаев (конфликты должны быть довольно редкими, поскольку они возникают в операционных системах с ручным управлением).

Это случай использования очень похож на один @cloutiertyler комментировал , где ни @franklinyu «сек решение , ни многоступенчатой не строит комментировал от @ cpuguy83 применяются:

где:

  • Шаги от A до C точно такие же, как от B до D (dockerfileAC).
  • Команда разработчиков B ничего не знает о C, D или E.
  • Команда разработчиков C ничего не знает о B, D или E.

Пользователь, желающий создать D (и / или E), должен иметь доступ к dockerfileAC, но не обязательно знать о dockerfileAB. Следовательно, пользователь должен лучше понимать одну зависимость (C), чем другую (B). В идеале должна быть возможность полагаться на команды A и B и просто строить D как A + (diff(B,A) + diff(C,A)) (слияние) или A + diff(B,A) + diff(C,A) (перебазирование).

Поскольку GHDL не является веб-службой, а VUnit не является веб-клиентом, оба инструмента необходимо установить в одном образе / контейнере (E). Многоступенчатые сборки бесполезны, потому что нам нужно создать (возможно, неизвестный) файл докеров с двумя метками FROM , это не одна прямая цепочка.

Если найти этот вариант использования, похожий на слияние / перебазирование двух веток git: иногда нет конфликтов, иногда конфликты легко разрешаются, иногда его невозможно объединить вообще, потому что нет общей истории ... Есть ли какой-нибудь инструмент, официальные или внешние, которые предоставляют эту функцию? Обратите внимание: это нормально, если инструмент просто экспортирует два изображения в ветки git и фактически использует git для слияния.

Удивительно, но это все еще проблема и тема. Насколько сложно «ВКЛЮЧИТЬ какое-то изображение», затем при его разборе проверьте совместимость базы (в цепочке FROM) и, если да, выполните оставшуюся часть ЭТОГО файла в этот момент (как если бы я скопировал Dockerfile из проекта и вставил в мою)?

В этом контексте отговорка "люди будут делать плохие вещи, которых они не осознают" абсурдна. Это уже безумно сложно, и поэтому нам это нужно, чтобы упростить его.

@rainabba Это совершенно бесполезный комментарий.
По сути, есть две причины, по которым это не делается:

  1. Это не так легко
  2. Никто не нашел времени на работу.

На самом деле обычно и то, и другое.

  1. Это проблема синтаксического анализа и замены строк, которую любой новый кодировщик мог бы решить за все 10 минут, ЕСЛИ бы знал, где именно в коде. Я не говорю, что его можно было бы использовать во всех случаях, но для тех ограниченных случаев, которые я вижу здесь снова и снова (где базы являются обычным явлением), это бесполезный трюк.

  2. Конечно, нет, в этом потоке есть ~ 102 причины, по которым это нельзя или не следует делать, так почему же кто-то может думать об этом, несмотря ни на что?

С другой стороны, мой комментарий служит (как и многие другие здесь), чтобы продемонстрировать, что существует потребность и с надеждой повлиять либо на препятствующие отношения, либо, по крайней мере, действовать как напоминание. Если это «совершенно бесполезно», то вы только что объяснили, почему эта проблема (игнорируемый запрос функции) все еще существует и активна, а не техническая.

Это намного больше , чем разбор строки.
Docker и Dockerfile используют миллионы людей. Добавление API - это важная вещь ... даже за пределами этого базовая реализация не является «синтаксическим анализом строки».

В любом случае предложений по решению проблемы много, и это очень старый и закрытый вопрос.

Я действительно думаю, что если Docker не найдет чистого решения для этого сценария, он, вероятно, будет заменен любым инструментом, который это выяснит.

Я заметил, что один из моих коллег использует следующий шаблон, который может быть подходящим решением:

ARG from
FROM $from
... rest of dockerfile

Я сам не пробовал, поэтому не уверен, как он будет работать на практике, например, как он ведет себя с кешированием и т. Д.

Действительно, это очень важная проблема, и до сих пор не решена должным образом. Я удивлен, что такая большая компания, как Docker, еще не взялась за это дело.

Всего лишь два цента ... В данный момент я только изучаю Docker и чувствую, что что-то вроде INCLUDE было бы очень полезно. Мне понравился приведенный выше пример множественного наследования, и я хотел ответить на комментарии о возможных проблемах и конфликтах с ним.

Множественное наследование сложно на любом языке, который его поддерживает, но при возникновении конфликта создатель файла Docker должен переосмыслить то, что он делает, и начать заново. Docker должен просто создать образ, а не пытаться доказать, что сборка не имеет проблем.

@cosminonea

Мне кажется, что-то вроде INCLUDE было бы очень полезно

У меня есть поддержка макросов в https://github.com/larytet/dockerfile-generator/, я тоже могу поддерживать "включить".

Это было бы упущено. Цель не в том, чтобы включать Dockerfile
определение. Цель состоит в том, чтобы включить образ докера. Это будет
кажутся абсурдными, потому что это не в моей голове:

из Fedora
включить ubuntu / ubuntu
включить debian / debian

Разумно ожидать, что это начнется с образа федоры.
Затем добавьте образ для ubuntu в папку / ubuntu. Затем добавил
образ для debian в каталоге / debian.

Это, конечно, абсурд, поэтому я хочу смешать кучу операционных
системы в один образ? Но более полезным примером может быть:

из Fedora
включить plex / plex
включить commericalremover / plex / add-on / commericalremover

Теперь в этом случае есть больше смысла. В том, что если это другие изображения
у меня нет рабочих конкретных компонентов, у меня есть простой способ сделать вещи
модульный.

В среду, 8 августа 2018 в 15:48, Аркадий Мясников [email protected]
написал:

Я чувствую что-то вроде ВКЛЮЧИТЬ
У меня есть поддержка макросов в
https://github.com/larytet/dockerfile-generator/ Я мог бы добавить "включить"
поддержка тоже.

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/3378#issuecomment-411529506 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/ADBcWAtBDEp_LXpW3HUkHd3Pw5IVAXvqks5uO0ChgaJpZM4BWkJ9
.

Последнее уже возможно; COPY --from принимает как этап сборки, так и изображение, например;

FROM busybox

COPY --from=alpine:latest / /
COPY --from=docker:latest /usr/local/bin/docker /usr/local/bin/

Редактировать; или взять реальный пример;

FROM fedora

COPY --from=ubuntu:latest / /ubuntu/
COPY --from=debian:latest / /debian/

Точно. Вот почему я бы подумал об обновлении 2017 года, в котором добавлено «КОПИРОВАТЬ
--from "как завершивший исходный запрос. Абсолютно
Больше я ничего не ожидал от этого билета.

Идеи, которые возникли позже, такие как автоматическое изменение настроек включения, будут
приятные особенности. Но они выходят за рамки первоначального запроса.

С уважением,

Счет

В четверг, 9 августа 2018 г., в 12:55, Себастьян ван Стейн [email protected]
написал:

Последнее уже возможно; COPY --from принимает как
build-stage, или изображение, например, так;

ОТ busybox

КОПИРОВАТЬ --from = alpine: latest / /
КОПИРОВАТЬ --from = docker: latest / usr / local / bin / docker / usr / local / bin /

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/3378#issuecomment-411824851 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/ADBcWPE738cs9xf3ZHSOaUd1foI1XVIQks5uPGmYgaJpZM4BWkJ9
.

@thaJeztah Использование многоступенчатых сборок для этого по-прежнему требует, чтобы вы знали, какие файлы _exactly_ копировать из каждого изображения; это даже сложнее поддерживать, чем копировать установочный код из другого изображения.

Конечно, объединить образы Docker нетривиально. Поскольку во время сборки можно запускать произвольные сценарии, процесс сборки сопротивляется любой общей попытке автоматического обнаружения конфликтов; проблема с остановкой говорит привет! Лучшее, что вы можете сделать (не считая значительного ограничения того, что могут делать сборки), - это определить точную семантику: скажем, последний FROM / INCLUDE побеждает (например, если они "записывают" один и тот же файл) или сбой при конфликте на уровне файловой системы или ....

Иногда указывается, что проблема с разными "базовыми" изображениями (stretch vs ubuntu vs alpine vs ...), однако, _is_ проста: требуется, чтобы DAG зависимостей изображений имел не только один источник (текущее изображение), но и один приемник. (общий «предок» всех изображений в «иерархии»).

В конечном итоге, конечно, вы получите мусор в мусоре - правда ли, что это когда-нибудь по-другому?

FWIW, мои варианты использования:

  1. Запуск веб-приложения Tomcat с базой данных PostgreSQL и хранилищем объектов S3.
    Хотя это можно решить с помощью Docker Compose, один контейнер может быть лучше.
  2. Многоязычные сборки запускаются в контейнерах Docker (например, на Jenkins, Circle CI, ...).
    Существуют официальные образы для наиболее популярных наборов инструментов, но создание единого контейнера, способного обрабатывать более одного запуска, как раз в той проблеме, которая обсуждается здесь.

@reitzig , если вам нужна динамическая генерация файлов Docker, я предлагаю добавить язык для конкретной предметной области. Есть несколько известных мне примеров.

@reitzig Это не единственный вариант. Правильный вариант - ограничить INCLUDE, чтобы избежать больших проблем. INCLUDE не могут наследовать. Вот оно. Простой. Все еще невероятно полезно.

Этот запрос функции популярен, но Docker бесплатный, как в Beer, но ни в коем случае не бесплатный, как в Freedom.

@rjurney С включением поддержки buildkit с 18.06, пользователи могут предоставить свой собственный синтаксический анализатор интерфейса для сборщика. Уже существует официальный (от Docker Inc) экспериментальный парсер Dockerfile, который включает в себя множество новых функций (поддержка секретов для начинающих).

Конечно, вы также можете добавить свое собственное поведение «ВКЛЮЧИТЬ» в пользовательский интерфейс Dockerfile или можете сделать что-то совершенно другое, кроме Dockerfile (есть пример для buidpacks).

Чтобы использовать настраиваемый интерфейс, просто нужно указать Docker на изображение, которое может его обработать. Сделайте это как комментарий к первой строке вашего Dockerfile (или что-то еще) syntax = myCustomFrontendImage

Подробнее здесь:
https://docs.docker.com/develop/develop-images/build_enhancements/#overriding -default-frontends

При включенном buildkit Docker может создавать все, что вы хотите (даже не в формате Dockerfile), с любыми функциями, которые вам нужны.

Этот запрос функции популярен, но Docker бесплатный, как в Beer, но ни в коем случае не бесплатный, как в Freedom.

Каким бы оффтопом ни была эта заметка, я думаю, следует отметить, что вы ошибаетесь. Благодаря лицензированию Docker Apache, каждый может свободно разрабатывать и разрабатывать собственный интерпретатор для Dockerfiles, который предоставляет функции, разработанные здесь. Если они будут осторожны, полученные образы будут совместимы с существующими средами выполнения / инструментами Docker.
Конечно, разработчики проекта Docker также могут не включать такую ​​функцию в свою вилку (оригинал?).

@reitzig Это, очевидно, просто бессмысленная напыщенная речь без фактического упоминания того, что такое свободные программы. Конечно, Moby - это бесплатное программное обеспечение.

Я не знал, что теперь у него есть лицензия Apache. Прошу прощения за замечание и
думаю, это здорово!

Рассел Джурни @rjurney http://twitter.com/rjurney
Рассел. [email protected] LI http://linkedin.com/in/russelljurney FB
http://facebook.com/jurney datasyndrome.com

В среду, 16 января 2019 г., в 4:17, Рафаэль Р. [email protected] написал:

Этот запрос функции популярен, но Docker бесплатен, как в Beer, но не от
любой означает Свободный, как в Freedom.

Каким бы оффтопом ни была эта заметка, я думаю, следует отметить, что вы
неправильный. Благодаря лицензированию Docker Apache у каждого есть свобода
fork и разработать собственный интерпретатор для файлов Docker, который предоставляет
функции, разработанные здесь. Если они будут осторожны, полученные изображения будут
совместим с существующими средами выполнения / инструментами Docker.
Конечно, разработчики проекта Docker также могут не
объединить такую ​​фичу в свою вилку (оригинал?).

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/3378#issuecomment-454758482 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AACkpdj_YO76ge79bm4G8FBmhOdbjhO9ks5vDxhvgaJpZM4BWkJ9
.

Извините, я плохо спал и ошибся. Мой комментарий остается в силе.
Бесплатное, как в Beer, означает Apache. Свобода как в «Свобода» означает общественный контроль.
Проект Apache или другая форма управления.

Рассел Джурни @rjurney http://twitter.com/rjurney
Рассел. [email protected] LI http://linkedin.com/in/russelljurney FB
http://facebook.com/jurney datasyndrome.com

В среду, 16 января 2019 г., в 12:32 Рассел Джурни [email protected]
написал:

Я не знал, что теперь у него есть лицензия Apache. Прошу прощения за замечание и
думаю, это здорово!

Рассел Джурни @rjurney http://twitter.com/rjurney
Рассел. [email protected] LI http://linkedin.com/in/russelljurney FB
http://facebook.com/jurney datasyndrome.com

В среду, 16 января 2019 г., в 4:17, Рафаэль Р. [email protected]
написал:

Этот запрос функции популярен, но Docker бесплатен, как в Beer, но не от
любой означает Свободный, как в Freedom.

Каким бы оффтопом ни была эта заметка, я думаю, следует отметить, что вы
неправильный. Благодаря лицензированию Docker Apache у каждого есть свобода
fork и разработать собственный интерпретатор для файлов Docker, который предоставляет
функции, разработанные здесь. Если они будут осторожны, полученные изображения будут
совместим с существующими средами выполнения / инструментами Docker.
Конечно, сопровождающие проекта Docker также могут
не объединять такую ​​фичу в свою вилку (оригинал?).

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/3378#issuecomment-454758482 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AACkpdj_YO76ge79bm4G8FBmhOdbjhO9ks5vDxhvgaJpZM4BWkJ9
.

Бесплатное, как в Beer, означает Apache.

Не согласен. Бесплатное ПО может быть проприетарным.

Свобода как в «Свобода» означает общественный контроль.

Что такое общественный контроль? Проекты в ведении фонда? Значит, вы считаете VS Code, Atom Editor и Ubuntu несвободными программами? Тогда ваше определение значительно отличается от того, что предложено FSF, EFF и многими другими организациями.

Я согласен с тем, что Docker Inc не ведет активных дискуссий с сообществом по этому вопросу, но это не имеет ничего общего с «Free as in Freedom».

Извините, ребята, давайте не будем проводить такого рода обсуждения в системе отслеживания проблем.

Я согласен с тем, что Docker Inc не ведет активных обсуждений с сообществом по этому вопросу.

Мы сделали возможным поддержку любого формата сборки, который вы хотите иметь, с помощью docker build . «Официальный» формат файла Dockerfile не поддерживает эту опцию, но это не означает, что docker build не может ее использовать.
Посмотрите https://matt-rickard.com/building-a-new-dockerfile-frontend/ в качестве примера создания пользовательского интерфейса, который работает с docker build .
Обратите внимание, что этот интерфейс является примером того, как вы можете делать что-то совершенно отличное от формата Dockerfile, но это не обязательно. Вы можете взять существующий формат Dockerfile и добавить свои собственные функции, если хотите.

Что касается добавления чего-либо в официальный формат Dockerfile ... Я скажу, что предложения всегда приветствуются, формат поддерживается в https://github.com/moby/buildkit.
Однако имейте в виду, что каждая новая функция означает новое бремя поддержки, в том числе часто ограничение того, что можно сделать в будущем.

Я думаю, что многие варианты использования для объединения нескольких файлов Dockerfile могут быть решены с помощью новых функций в Dockerfile ... в частности, возможности COPY --from и RUN --mount из произвольных изображений.

Если бы этот гипотетический INCLUDE мог бы просто создать дополнительные контейнеры в качестве имплицитной детали, при этом мне НЕ пришлось бы указывать @ # $%, это значительно уменьшило бы количество разочарований, связанных с неявной и хитрой продажей составных контейнеров. Я действительно просто хочу вернуться к приложению и предоставлению функциональности. Извините за плохие флюиды, но я нуб докеров / контейнеров и столкнулся с той же неразберихой, которую уже выразили многие другие плакаты.

Что, если бы вы могли это сделать:

              /--- python:3.8.3-alpine3.12 ---\
             /                                 \
alpine:3.12.0                                   custom image (with both python and rust)
             \                                 /
              \----- rust:1.44-alpine3.12 ----/

_Обратите внимание, что оба изображения являются потомками одного и того же изображения. Это ключ! _

Так просто:

FROM alpine:3.12.0
INCLUDE rust:1.44-alpine3.12
INCLUDE python:3.8.3-alpine3.12

_По сравнению с инструкцией «COPY --from image» (многоэтапные сборки) вам не придется думать о деталях реализации (какие файлы / переменные среды копировать) ._

Как это выглядит сейчас, если вы хотите объединить изображения

FROM alpine:3.12.0

# INCLUDE rust:1.44-alpine3.12
COPY --from=rust:1.44-alpine3.12 / /
ENV RUSTUP_HOME=/usr/local/rustup \
    CARGO_HOME=/usr/local/cargo \
    PATH=/usr/local/cargo/bin:$PATH \
    RUST_VERSION=1.44.1

# INCLUDE python:3.8.3-alpine3.12
COPY --from=python:3.8.3-alpine3.12 / /
ENV PATH /usr/local/bin:$PATH
ENV LANG C.UTF-8
ENV GPG_KEY E3FF2839C048B25C084DEBE9B26995E310250568
ENV PYTHON_VERSION 3.8.3
ENV PYTHON_PIP_VERSION 20.1.1
ENV PYTHON_GET_PIP_URL https://github.com/pypa/get-pip/raw/eff16c878c7fd6b688b9b4c4267695cf1a0bf01b/get-pip.py
ENV PYTHON_GET_PIP_SHA256 b3153ec0cf7b7bbf9556932aa37e4981c35dc2a2c501d70d91d2795aa532be79

_ENV-инструкции скопированы из файлов Docker этих образов._


Это также позволит значительно улучшить повторное использование контейнеров и упростить сборку вещей, на компиляцию или сборку которых в противном случае уйдет много времени!

Учтите, что при таком подходе программа должна быть скомпилирована только один раз для каждой версии платформы / базового образа - и ее легче использовать повторно, чем реализовывать самостоятельно. Подумайте только, сколько раз «колесо» переопределялось в C ++ из-за отсутствия хорошего / универсального менеджера пакетов. Хотим ли мы, чтобы подобная ситуация возникла и с Docker?

@bergkvist , см. https://github.com/moby/moby/issues/3378#issuecomment -381449355 и https://github.com/moby/moby/issues/3378#issuecomment -381641675.

Мне кажется, что ни одно из предлагаемых вами решений не соответствует схеме. Вместо этого вы делаете:

              /--- python:3.8.3-alpine3.12 ---\
             /                                 \
alpine:3.12.0                                   \
             \                                   \
              \----- rust:1.44-alpine3.12 --------\ custom image 

Итак, любой файл, который был изменен в ржавчине , перезаписывается python . Объединение их без копирования одного на другое потребует некоторого слияния.

@eine Да, в случае конфликтов файлы будут перезаписаны. Это правда. Таким образом, симметричная фигура будет особым случаем, когда никакие (соответствующие) файлы не перекрываются. Ваша версия рисунка более общая.

Я считаю, что оба изображения наследуются от одного и того же образа, поскольку вероятность возникновения критических конфликтов может быть незначительной.

Я предполагаю, что могут возникнуть конфликты, связанные с файлами диспетчера пакетов. Если оба образа использовали диспетчер пакетов для установки разных вещей. Я не уверен, есть ли какие-то другие «общие конфликты», подобные тому, которые можно было бы разрешить в каком-то особом случае.

Слияние двух файлов далеко не прямолинейно. Я думаю, что в общем случае лучше просто перезаписать, чем пытаться быть умным. По крайней мере, тогда легче отлаживать, когда что-то не работает.

Поскольку я прокомментировал здесь 4 дня назад, я решил изучить Golang и изучить код внешнего интерфейса для кода moby / buildkit.

Теперь я создал настраиваемый интерфейс, который принимает операторы INCLUDE, как я обсуждал выше.

#syntax=bergkvist/includeimage
FROM alpine:3.12.0
INCLUDE rust:1.44-alpine3.12
INCLUDE python:3.8.3-alpine3.12

Чтобы использовать собственный синтаксис, не забудьте установить DOCKER_BUILDKIT = 1 при сборке.

DOCKER_BUILDKIT=1 docker build -t myimage .

Код доступен здесь: https://github.com/bergkvist/includeimage
И изображение в Docker Hub: https://hub.docker.com/r/bergkvist/includeimage

Была ли эта страница полезной?
0 / 5 - 0 рейтинги