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


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.