Docker и Makefile Build - PullRequest
       5

Docker и Makefile Build

0 голосов
/ 19 февраля 2019

Я надеюсь использовать Dockerfile для создания довольно большой базы кода из исходного кода.Исходный код написан на C ++, а система сборки написана на Makefile .В настоящее время мой Dockerfile выглядит следующим образом:

FROM ubuntu:16.04

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        vim g++ make && \
    rm -rf /var/lib/apt/lists/*

COPY src /src # `src` folder contains the source code
WORKDIR /src
RUN make && make all

Моя основная проблема в этом Dockerfile заключается в следующем: предположим, что позже, когда я изменю какую-то крошечную часть большой кодовой базы и повторно выполню docker build команда, какое из следующих действий произойдет?

  1. Docker выполняет копирование еще раз и выясняет зависимость сборки make.
  2. Docker ничего не делает, потому что Dockerfile не был изменен.
  3. Docker создает всю кодовую базу с самого начала.

Если происходит второе или третье, есть ли лучший вариант, чем поставить makeкоманда внутри Dockerfile?Должен ли я выполнить его как часть docker run и смонтировать каталог с исходным кодом в контейнер Docker?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Есть два возможных ответа на этот вопрос.

Если у вас есть файл .dockerignore, который включает *.o, или у вас настроено отдельное дерево сборки, то, когда вы достигнете строки RUN make,образ будет содержать все исходные файлы и ни один из объектных файлов, и сборка будет выполняться с нуля.Это самый «чистый» ответ - вы должны получить очень последовательный результат сборки - но на самом деле это может занять некоторое время.

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

Если у вас уже есть система сборки, основанная в основном на Make, я мог бы придерживаться этогои предпочитают модель «делать все в Make» модели «делать все в Docker».В GNU Make вы можете написать фрагмент, подобный следующему:

DOCKER_TAG := $(shell date +%Y%m%d)

.PHONY: docker

docker:
        $(MAKE) install DESTDIR=docker/dist
        cp Dockerfile docker
        docker build -t me/myapp:$(DOCKER_TAG) docker

Это также дает вам практический эффект многоэтапной сборки (вы предварительно скомпилировали приложение, поэтому вам не нужен набор инструментов вDocker ведет трубопровод куда угодно. Так же, как вы сейчас sudo make install, вы sudo make docker создадите образ Docker.

0 голосов
/ 22 февраля 2019

Большое спасибо за все ответы.

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

  • . Как ответил @molamk, Docker скопирует файлы и начнет сборку с самого начала .Причина в том, что для команды COPY Docker использует механизм контрольной суммы, чтобы проверить, были ли файлы изменены или нет.Следовательно, Docker может точно определить, необходима ли повторная копия, и сделать недействительными все кэшированные слои (включая make build) после слоя COPY.
  • В моем случае, когда я хочу изменить детальбольшой базы кода, включая сборку внутри Dockerfile, - ужасная идея, поскольку это означает, что каждый раз, когда мне нужно ждать несколько часов, чтобы изменения вступили в силу.Поэтому я включил обязательное условие сборки в Dockerfile и подключил исходный каталог к ​​контейнеру, полученному при запуске образа предварительного требования.
0 голосов
/ 19 февраля 2019

Docker выполняет копирование еще раз и выясняет зависимость сборки от make

Да .Он скопирует ваш источник в указанное место назначения в контейнере

Docker ничего не делает, потому что Dockerfile не был изменен.

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

Docker создает всю кодовую базу с самого начала.

По умолчанию yes .Если вы не скопировали предварительно скомпилированные артефакты в свой контейнер (чего вы не должны делать), то он будет перестраивать ваш код с нуля.

есть ли лучший вариант, чем поместитьсделать команду внутри Dockerfile?

Поместить команду make в Dockerfile - лучший вариант .Одна из наиболее важных причин, по которой люди используют Docker (если не самая важная), заключается в предсказуемых сборках

Note

Возможный «лучший способ» означает использование многоступенчатых сборок для разделения вашего "контейнера-строителя" и вашего "контейнера с двоичным файлом" .Это также дает вам меньшие "окончательные" изображения, поскольку вы можете создавать их из alpine или scratch .Таким образом, ваш «окончательный» контейнер не должен будет включать ненужные библиотеки / программное обеспечение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...