Подтвердить что ты не робот

Команда Docker RUN: когда командам группы, когда не нужно?

Я видел две различные методологии использования команды RUN в Dockerfile, которую я назову v1 и v2.

v1

Одна команда на строку

FROM ubuntu/latest
ENV DEBIAN_FRONTEND noninteractive

RUN apt-get update
RUN apt-get -y install php5-dev
RUN libcurl4-openssl-dev
...

v2

Несколько команд на строку

FROM ubuntu/latest
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
    apt-get -y install \
        php5-dev \
        libcurl4-openssl-dev
...

Обе методологии имеют свои преимущества, самый очевидный подход к использованию кеширования. Какие еще причины могут использовать один подход над другим?

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

4b9b3361

Ответ 1

Чтобы ответить на этот вопрос, вы должны сначала понять концепцию "commits" и кэширование докеров. В конце я предоставляю вам эмпирическое правило.

Фиксация

Вот пример:

# Dockerfile
FROM ubuntu/latest
RUN touch /commit1
RUN touch /commit2

При запуске docker build . докер выполняет следующие действия:

  • Он запускает контейнер из образа ubuntu/latest.
  • Он запускает первую команду (touch /commit1) в контейнере и создает новое изображение.
  • Повторное использование образа, созданного в # 2, для запуска нового контейнера.
  • Он запускает вторую команду (touch /commit2) во втором контейнере и создает новое изображение.

Что вам нужно понять, так это то, что если вы группируете команды в одном выражении RUN, то все они будут выполняться в одном контейнере и будут соответствовать одному фиксации.

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

Кэширование

Когда вы запускаете docker build ., докер повторно использует изображения, созданные ранее. Другими словами, если вы отредактировали вышеупомянутый файл Docker, чтобы включить RUN touch /commit3 в конец, и запустили docker build ., тогда Docker повторно использовал изображение, созданное в # 4.

Это имеет значение, потому что когда вы включаете RUN apt-get update в свой файл Docker, тогда не гарантируется, что это будет работать за секунды до RUN apt-get install php5.

Насколько вам известно, фиксация с помощью RUN apt-get update могла быть создана месяц назад. Кэш APT больше не обновляется, но Docker все еще использует его.

Правило большого пальца

Обычно проще группировать все в одной команде RUN и начинать разрывать его, когда вы хотите начать использовать кеширование (например, ускорить процесс сборки).

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

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

Заключение

В вашем примере v2 верен, а v1 неверен (потому что он контрпродуктивен для кэширования apt-get update).