Ответ 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
).