Как заставить Docker для чистой сборки образа


819

Я построил образ Docker из файла Docker с помощью приведенной ниже команды.

$ docker build -t u12_core -f u12_core .

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

Step 1 : FROM ubuntu:12.04
 ---> eb965dfb09d2
Step 2 : MAINTAINER Pavan Gupta <pavan.gupta@gmail.com>
 ---> Using cache
 ---> 4354ccf9dcd8
Step 3 : RUN apt-get update
 ---> Using cache
 ---> bcbca2fcf204
Step 4 : RUN apt-get install -y openjdk-7-jdk
 ---> Using cache
 ---> 103f1a261d44
Step 5 : RUN apt-get install -y openssh-server
 ---> Using cache
 ---> dde41f8d0904
Step 6 : RUN apt-get install -y git-core
 ---> Using cache
 ---> 9be002f08b6a
Step 7 : RUN apt-get install -y build-essential
 ---> Using cache
 ---> a752fd73a698
Step 8 : RUN apt-get install -y logrotate
 ---> Using cache
 ---> 93bca09b509d
Step 9 : RUN apt-get install -y lsb-release
 ---> Using cache
 ---> fd4d10cf18bc
Step 10 : RUN mkdir /var/run/sshd
 ---> Using cache
 ---> 63b4ecc39ff0
Step 11 : RUN echo 'root:root' | chpasswd
 ---> Using cache
 ---> 9532e31518a6
Step 12 : RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
 ---> Using cache
 ---> 47d1660bd544
Step 13 : RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
 ---> Using cache
 ---> d1f97f1c52f7
Step 14 : RUN wget -O aerospike.tgz 'http://aerospike.com/download/server/latest/artifact/ubuntu12'
 ---> Using cache
 ---> bd7dde7a98b9
Step 15 : RUN tar -xvf aerospike.tgz
 ---> Using cache
 ---> 54adaa09921f
Step 16 : RUN dpkg -i aerospike-server-community-*/*.deb
 ---> Using cache
 ---> 11aba013eea5
Step 17 : EXPOSE 22 3000 3001 3002 3003
 ---> Using cache
 ---> e33aaa78a931
Step 18 : CMD /usr/sbin/sshd -D
 ---> Using cache
 ---> 25f5fe70fa84
Successfully built 25f5fe70fa84

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


10
Кроме того, вы должны стараться свести к минимуму количество RUNдиректив.
— tripleee

4
@tripleee Можете ли вы объяснить, почему?
— Я.

9
@Ya. Раньше Docker всегда создавал отдельный слой для каждой RUNдирективы, поэтому Dockerfileсо многими RUNдирективами потребовалось бы огромное количество дискового пространства; но это, по-видимому, несколько улучшилось в последних версиях.
— tripleee

Когда я пытаюсь docker-compose up -d, где я могу использовать --no-cache?
— Оо

1
@ Ну, это невозможно. Сначала нужно сделать, docker-compose build --no-cacheа потомdocker-compose up -d
— Мартин Мелка

Ответы:


1446

Там есть --no-cacheвариант:

docker build --no-cache -t u12_core -f u12_core .

В старых версиях Docker вам нужно было пройти --no-cache=true, но это уже не так.


89
Также обратите внимание, что --no-cacheработает с docker-compose build.
— Blackus

42
Вы также можете использовать --pull. Это скажет докеру получить последнюю версию базового образа. Это необходимо в дополнение к тому, --no-cacheесли у вас уже есть базовый образ (например, ubuntu/latest), и базовый образ был обновлен с момента последнего его извлечения. Смотрите документы здесь .
— Коллин Кроулл

2
@CollinKrawll: --pullвариант сделал свое дело для меня. Просто --no-cache, сборка еще сломалась. Положите, --pullа построить работает! Спасибо!
— Erdős-Bacon

1
Если кто-то вызывает сборку Docker, разве не предполагается, что он хочет восстановить без кеша? В каком случае кто-то захочет создать изображение и использовать ранее созданное изображение? <rant> Я только что потерял день, потому что предыдущая сборка завершилась неудачно, но завершилась «успешно», и я использовал сломанное изображение, не понимая, почему не работали обновления для скрипта сборки </ rant>
— Джефф

3
@Jeff Когда вы разрабатываете образ докера, сборка докера будет только возвращать измененные слои / шаги. Если у меня есть пять шагов, и я добавляю новый шаг с индексом 3, слои, связанные с шагами 1 и 2, можно использовать повторно. Это значительно ускоряет процесс разработки
— хлопья

130

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

docker system prune

Команда запросит у вас подтверждение:

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all networks not used by at least one container
    - all images without at least one container associated to them
Are you sure you want to continue? [y/N]

Это, конечно, не прямой ответ на вопрос, но может спасти некоторые жизни ... Это спасло мою.


8
добавление -a -f делает его лучше
— Рави

1
@IulianOnofrei работает для меня,Docker version 17.09.0-ce, build afdb6d4
— Per Lundberg

1
@PerLundberg, я обновился dockerдо той же версии, и она работает, спасибо.
— Юлиан

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

1
Это даже приведет к удалению изображений остановленных контейнеров, вероятно, того, что вам не нужно. В последних версиях Docker есть команда docker builder pruneдля очистки кэшированных слоев сборки. Просто попал в ловушку после слепого копирования команд из переполнения стека.
— Злой Азраэль

59

Команда docker build --no-cache .решила нашу похожую проблему.

Наш Dockerfile был:

RUN apt-get update
RUN apt-get -y install php5-fpm

Но должно было быть:

RUN apt-get update && apt-get -y install php5-fpm

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

Смотрите: Лучшие практики для написания Dockerfiles


10
«Должен был» вводит в заблуждение. Если Docker увидит, что у него есть кэшированная копия, RUN apt-get update && apt-get -y install php5-fpmвы все равно увидите, что он снова используется со старым содержимым.
— tripleee

10
На самом деле все же имеет смысл присоединиться к ним, потому что в противном случае, если вы измените строку установки, он все равно будет использовать кеш старого пакета, который часто будет иметь проблемы, если кеш устарел (обычно файлы будут 404.)
— Джон Чедвик

19

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

--no-cache - Это приведет к восстановлению уже доступных слоев

--pull - Это вызовет извлечение базового изображения, на которое ссылается FROM, и гарантирует получение последней версии.

Поэтому полная команда будет выглядеть так:

docker build --pull --no-cache --tag myimage:version .

Те же параметры доступны для docker-compose:

docker-compose build --no-cache --pull

13

Я бы не рекомендовал использовать --no-cacheв вашем случае.

Вы выполняете несколько установок с шага 3 по 9 (кстати, я бы предпочел использовать один вкладыш), и если вы не хотите, чтобы эти шаги накладывались повторно при каждом создании образа, вы можете измените ваш Dockerfileвременный шаг до вашей wgetинструкции.

Я использую, чтобы сделать что-то подобное RUN ls .и изменить его на RUN ls ./затем RUN ls ./.и так далее для каждой модификации, сделанной на tarball, полученнойwget

Конечно, вы можете сделать что-то вроде RUN echo 'test1' > test && rm testувеличения числа 'test1для каждой итерации.

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


3
Способность быть в состоянии не использовать кэш после определенного момента это функция по просьбе многих (см github.com/moby/moby/issues/1996 альтернатив для очистки кэша)
— leszek.hanusz


6

Большая часть информации здесь верна.
Вот подборка их и мой способ их использования.

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

Рекомендуемый подход:

1) Принудительное выполнение каждого шага / инструкции в Dockerfile:

docker build --no-cache 

или с docker-compose build:

docker-compose build --no-cache

Мы также можем объединить это с upподкомандой, которая воссоздает все контейнеры:

docker-compose build --no-cache &&
docker-compose up -d --force-recreate 

Этим способом используется не кеш, а построитель докеров и базовый образ, на который ссылается FROMинструкция.

2) Протрите кэш Docker Builder (если мы используем Buildkit, нам, вероятно, это нужно):

docker builder prune -af

3) Если мы не хотим использовать кэш родительских изображений, мы можем попытаться удалить их, например:

docker image rm -f fooParentImage

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

Более радикальный подход:

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

1) Удалите все изображения, не связав с ними хотя бы один контейнер:

docker image prune -a

2) Удалить еще много вещей:

docker system prune -a

Это говорит:

ПРЕДУПРЕЖДЕНИЕ! Это удалит:
  - все остановленные контейнеры
  - все сети не используются хотя бы одним контейнером
  - все изображения без как минимум одного связанного с ними контейнера
  - весь кеш сборки

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


3

Вы можете управлять кешем с помощью docker builder

Чтобы очистить весь кэш без запроса: docker builder prune -af

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.