Як змусити Докера до чистого складання зображення


812

Я створив зображення 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

Кеш показує, що встановлено аероскоп. Однак я не знаходжу його всередині контейнерів, породжених із цього зображення, тому я хочу відновити це зображення без використання кешу. Як змусити Докера відновити чисте зображення без кешу?


10
Як сторону, ви, як правило, намагайтеся мінімізувати кількість RUNдиректив.
tripleee

4
@tripleee Ви можете пояснити, чому?
Я.

9
@Ya. Раніше Докер завжди створював окремий шар для кожної RUNдирективи, тому Dockerfileз багатьма RUNдирективами витрачалося б величезна кількість дискового простору; але це, мабуть, дещо покращилося в останніх версіях.
трійчатка

Коли я намагаюся docker-compose up -d, де я можу використовувати --no-cache?
Oo

@ Oo це неможливо. Спочатку потрібно зробити, docker-compose build --no-cacheа потімdocker-compose up -d
Мартін Мелька

Відповіді:


1439

Є --no-cacheваріант:

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

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


87
Також зауважте, що --no-cacheпрацює з docker-compose build.
Блекус

42
Ви також можете використовувати --pull. Це підкаже докеру отримати останню версію базового зображення. Це необхідно на додаток до того, --no-cacheякщо у вас вже є базове зображення (наприклад:), ubuntu/latestа базове зображення було оновлено з моменту останнього його натягування. Дивіться документи тут .
Collin Krawll

2
@CollinKrawll: Цей --pullваріант зробив для мене трюк. Просто --no-cacheбудівництво все-таки зламалося. Покладіть --pullтакож, будівництво працювало! Дякую!
Erdős-Bacon

1
Якщо хтось викликає docker build, чи не передбачається, що вони хочуть відновити без кешу? У якому випадку користувач хотів би створити образ і використати раніше вбудований образ? <rant> Я просто втратив день, тому що попередня збірка мовчала, але завершена "успішно", і я використовував розбитий образ, не розуміючи, чому оновлення сценарію збирання не працювали </rant>
Jeff

3
@Jeff Коли ви розробляєте зображення докера, збірка докера буде лише повторювати шари / етапи, які були змінені. Якщо у мене є п'ять кроків, і я додаю новий крок в індекс 3, шари, пов'язані з кроком 1 і 2, можна повторно використовувати. Це значно пришвидшує процес розробки
пластівці

129

У деяких екстремальних випадках ваш єдиний спосіб обійти повторювані збої у складанні:

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
Пер Лундберг

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
Значення "повинно було бути" вводить в оману. Якщо Докер побачить, що в ньому є кешована копія, RUN apt-get update && apt-get -y install php5-fpmви все одно побачите його повторно використовувати зі старим вмістом.
tripleee

10
Насправді все-таки є сенс приєднатись до них, бо в іншому випадку, якщо ви зміните інсталяційну лінію, він все одно буде використовувати старий кеш пакету, який часто матиме проблеми, якщо кеш застарілий (зазвичай файли будуть 404.)
Джон Чадвік

18

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

--no-cache - Це змусить відновити вже наявні шари

--pull - Це призведе до потягу базового зображення, на яке посилається FROM, гарантуючи, що ви отримали останню версію.

Тому повна команда буде виглядати приблизно так:

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

Такі ж варіанти є і для докер-композиту:

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

13

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

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

Я використовую, щоб зробити щось на кшталт RUN ls .і змінити це на RUN ls ./потім RUN ls ./.і так далі для кожної модифікації, зробленої на тарболі, отриманому користувачемwget

Звичайно, можна зробити щось на кшталт RUN echo 'test1' > test && rm testзбільшення кількості 'test1за кожну ітерацію.

Це виглядає брудно, але, наскільки я знаю, це найефективніший спосіб продовжувати користуватися кеш-системою Docker, що економить час, коли у вас багато шарів ...


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

13

Спробуйте докер-композицію docker-compose up -d --build --force-recreate


5

Більшість інформації тут правильна.
Ось добірка їх та мій спосіб їх використання.

Ідея полягає в тому, щоб дотримуватися рекомендованого підходу (будувати конкретний і не впливати на інші збережені докерські об'єкти) та спробувати більш радикальний підхід (не будувати конкретних і не впливати на інші збережені докерські об'єкти), коли цього недостатньо.

Рекомендований підхід:

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

У більшості випадків цих 3 речі цілком достатньо, щоб дозволити чітке складання нашого іміджу.
Тому ми повинні намагатися дотримуватися цього.

Більш радикальний підхід:

У кутових випадках, коли здається, що деякі об’єкти в кеш-пам'яті докера все ще використовуються під час збирання, і це виглядає повторюваним, ми повинні спробувати зрозуміти причину, щоб мати змогу дуже точно витерти пропущену частину. Якщо ми дійсно не знаходимо способу відновлення з нуля, є й інші способи, але важливо пам’ятати, що вони, як правило, видаляють набагато більше, ніж потрібно. Таким чином, ми повинні використовувати їх обережно в цілому, коли ми не знаходимось у місцевих умовах / середовищі розробників.

1) Видаліть усі зображення без прив’язаного до них одного контейнера:

docker image prune -a

2) Видаліть ще багато речей:

docker system prune -a

Це говорить:

УВАГА! Це видалить:
  - усі зупинили контейнери
  - всі мережі, які не використовуються щонайменше одним контейнером
  - всі зображення без принаймні одного контейнера, пов’язаного з ними
  - всі будують кеш

Використання команди super delete може бути недостатньою, оскільки вона сильно залежить від стану контейнерів (запущених чи ні). Коли цієї команди недостатньо, я намагаюся продумати ретельно, які контейнери докерів можуть спричинити побічні ефекти для нашої докерної збірки, і дозволити вихід цих контейнерів для того, щоб вони могли видалити їх командою.


3

Ви можете керувати кешем будівельника за допомогою docker builder

Щоб очистити весь кеш без запиту: docker builder prune -af

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.