img

Кэш Docker: как выполнить повторную сборку образа и очистить кэш Docker

 

С помощью контейнеров вы можете упаковать свое приложение и сделать его, таким образом, переносимым. В результате оно сможет работать в разных средах. Самая популярная платформа управления контейнерами – это Docker.

Кэш сборки 

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

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

Как оптимизировать кэш сборки

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

FROM nginx:1.21.6

# Update all packages { // Обновляем все пакеты }
RUN apt-get update && apt-get -y upgrade

# Use a custom startpage { // Используем пользовательскую начальную страницу }
RUN echo '<html><bod>My Custom Startpage</body></html>' > /usr/share/nginx/html/index.html

Теперь мы можем создать образ Docker:

$  docker build -t my-custom-nginx .

=> [1/3] FROM docker.io/library/nginx:1.21.6@sha256:e12...  5.8s
=> [2/3] RUN apt-get update && apt-get -y upgrade           3.6s
=> [3/3] RUN echo '<html><bod>My Custom Startpage...        0.2s

=> exporting to image                                       0.1s
=> exporting layers                                         0.1s
=> writing image                                            0.0s
=> naming to docker.io/library/my-custom-nginx

[+] Building 11.3s (7/7) FINISHED

В данном примере я удалил часть вывода для того, чтобы его было проще читать. Если вы создаете образ впервые, то вы могли заметить, что этот процесс занимает довольно много времени – в данном случае 11.3s.

Самый долгий шаг - apt-get update && apt-get -y upgrade. Время его выполнения зависит от того, сколько зависимостей обновляется и насколько высока скорость вашего интернета. Эта команда проверяет наличие обновлений пакетов в операционной системе и устанавливает их при их наличии.

А теперь вы можете выполнить эту команду снова и выиграть время, воспользовавшись кэшем сборки:

$ docker build -t my-custom-nginx .

=> [1/3] FROM docker.io/library/nginx:1.21.6@sha256:e1211ac1…   0.0s
=> CACHED [2/3] RUN apt-get update && apt-get -y upgrade        0.0s
=> CACHED [3/3] RUN echo '<html><bod>My Custom Startpage...     0.0s

=> exporting to image                                           0.0s
=> exporting layers                                             0.0s
=> writing image                                                0.0s
=> naming to docker.io/library/my-custom-nginx

Building 1.1s (7/7) FINISHED

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

FROM nginx:1.21.6

# Update all packages { // Обновляем все пакеты }
RUN apt-get update && apt-get -y upgrade

# Use a custom startpage { // Используем пользовательскую начальную страницу }
RUN echo '<html><bod>New Startpage</body></html>' > /usr/share/nginx/html/index.html

А теперь снова создадим образ:

$ docker build -t my-custom-nginx .

=> [1/3] FROM docker.io/library/nginx:1.21.6@sha256:e1211ac1…   0.0s
=> CACHED [2/3] RUN apt-get update && apt-get -y upgrade        0.0s
=> [3/3] RUN echo '<html><bod>My Custom Startpage...            0.2s

=> exporting to image                                           0.0s
=> exporting layers                                             0.0s
=> writing image                                                0.0s
=> naming to docker.io/library/my-custom-nginx

Building 2.1s (7/7) FINISHED

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

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

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

Как использовать параметр --no-cache для сборки Docker

Причины отключения кэширования сборки могут быть самые разные. Вы можете повторно произвести сборку образа на базе основного образа, не используя при этом кэшированные слои, но используя при этом параметр --no-cache

$ docker build -t my-custom-nginx .

=> CACHED [1/3] FROM docker.io/library/nginx:1.21.6@sha256:...  0.0s
=> [2/3] RUN apt-get update && apt-get -y upgrade               3.5s
=> [3/3] RUN echo '<html><bod>My Custom Startpage...            0.2s

=> exporting to image                                           0.1s
=> exporting layers                                             0.0s
=> writing image                                                0.0s
=> naming to docker.io/library/my-custom-nginx

Building 5.5s (7/7) FINISHED

Здесь были построены и созданы новые слои. docker build запустила в этот раз обе команды, то есть применила подход «все или ничего». Либо вы указываете параметр --no-cache, который позволит выполнить все команды, либо вы кэшируете по максимуму.

Как применить аргументы Docker для очистки кэша

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

FROM nginx:1.21.6
 
# Update all packages { // Обновляем все пакеты }
RUN apt-get update && apt-get -y upgrade

# Custom cache invalidation { // Обновление пользовательского кэша }
ARG CACHEBUST=1

# Use a custom startpage { // Используем пользовательскую начальную страницу }
RUN echo '<html><bod>New Startpage</body></html>' > /usr/share/nginx/html/index.html

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

$ docker build -t my-custom-nginx --build-arg CACHEBUST=$(date +%s) .

=> [1/3] FROM docker.io/library/nginx:1.21.6@sha256:e1211ac1...    0.0s
=> CACHED [2/3] RUN apt-get update && apt-get -y upgrade           0.0s
=> [3/3] RUN echo '<html><bod>My Custom Startpage...               0.3s

=> exporting to image                                              0.0s
=> exporting layers                                                0.0s
=> writing image                                                   0.0s
=> naming to docker.io/library/my-custom-nginx

Building 1.0s (7/7) FINISHED

Указав --build-arg CACHEBUST=$(date +%s), вы постоянно будете устанавливать для параметра новой значение, что будет приводить к повторной сборке всех последующих слоев. 

Заключение

Кэширование сборок в Docker – довольно полезная функция. Она ускоряет процесс сборки образов Docker за счет повторного использования слоев, которые были созданы ранее.

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

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

Ссылка
скопирована
Получите бесплатные уроки на наших курсах
Все курсы
Еще по теме:
img
Git Flow - это специальная система ветвления для Git. Она помогает команде лучше контролировать и добавлять различные версии проекта. В статье рассказываем, как ее использовать.
img
Мы рассмотрим несколько простых способов, с помощью которых вы можете управлять и отслеживать логи для своих контейнеров.
img
Узнайте, как использовать Git Hooks для автоматизации задач в рабочем процессе: от проверки коммитов до автоматического тестирования, и как настроить хуки для совместной работы в команде.
img
Откройте для себя, как канареечное развертывание может минимизировать риски при обновлении ПО. Узнайте, как постепенно внедрять новые функции и обеспечивать стабильность продукта с помощью этого метода.
img
Откройте для себя GitOps — революционный подход к управлению инфраструктурой через Git. Узнайте, как этот метод упрощает развертывание приложений и повышает надежность с помощью автоматизации и масштабируемости.