Я сделал простой образ через Dockerfile из Fedora (изначально 320 МБ).
Добавлен Nano (этот крошечный редактор размером 1 МБ), и размер изображения увеличился до 530 МБ. Кроме того, я добавил Git (30 МБ), а затем увеличил размер моего изображения до 830 МБ.
Разве это не безумие?
Я пытался экспортировать и импортировать контейнер для удаления истории / промежуточных изображений. Это усилие сэкономило до 25 МБ, теперь мой размер изображения составляет 804 МБ. Я также пытался запустить много команд на одной RUN
, но все же я получаю те же начальные 830 МБ.
У меня есть сомнения, стоит ли вообще использовать Docker. Я имею в виду, я едва что-то установил, и я ударил 1 Гб сверх. Если мне придется добавить некоторые серьезные вещи, такие как база данных и т. Д., У меня может быть недостаточно места на диске.
Кто-нибудь страдает от нелепого размера изображений? Как вы справляетесь с этим?
Разве мой Dockerfile ужасно неверен?
FROM fedora:latest
MAINTAINER Me NotYou <email@dot.com>
RUN yum -y install nano
RUN yum -y install git
но трудно представить, что здесь может пойти не так.
yum clean all
какое-либо влияние на размер?docker images
котором в последнем столбце говорится о здоровенных 830 МБ. Возможно, я не знаю, каков фактический размер моего образа, поскольку команда docker images утверждает, что эти 830 МБ виртуального размера. Но опять же, каков реальный размер изображения?Ответы:
Как сказал @rexposadas, изображения включают в себя все слои, и каждый слой включает в себя все зависимости для того, что вы установили. Также важно отметить, что базовые образы (например,
fedora:latest
обычно очень скудны). Вы можете быть удивлены количеством зависимостей, которые имеет установленное программное обеспечение.Я смог сделать вашу установку значительно меньше, добавив
yum -y clean all
в каждую строку:Важно сделать это для каждого RUN, перед тем как уровень будет зафиксирован, иначе удаление не приведет к удалению данных. Таким образом, в файловой системе объединения / копирования при записи очистка в конце фактически не уменьшает использование файловой системы, поскольку реальные данные уже передаются на более низкие уровни. Чтобы обойти это, вы должны очистить каждый слой.
источник
docker images
). Можно ли удалить / удалить / уничтожить эти старые слои? Чтобы быть более конкретным: я хотел бы полностью удалить (основываясь на вашем примере) изображения: 172743bd5d60, 3f2fed40e4b0, fd241224e9cf, 511136ea3c5a из истории, так что размер моего виртуального изображения более-менее совпадает с окончательным размером, здесь ~ 260 МБ ,docker export
и тогдаdocker import
снова. Это сгладит слои. Я не думаю, что это уменьшит размер, но я могу ошибаться.docker ps -s
указан реальный размер жесткого диска, который в моем случае был-1B
. Звучит разумно, минус 1 байт . Я получил немного места на жестком диске ... кажется законным.Изображения Docker не большие, вы просто создаете большие изображения.
scratch
Изображение 0B , и вы можете использовать, чтобы упаковать свой код , если вы можете скомпилировать код в статический бинарный. Например, вы можете скомпилировать вашу программу Go и упаковать ее сверху,scratch
чтобы получить полностью пригодное для использования изображение размером менее 5 МБ.Ключ в том, чтобы не использовать официальные изображения Docker, они слишком велики. Скретч не так уж практичен, поэтому я бы рекомендовал использовать Alpine Linux в качестве базового образа. Это ~ 5 МБ, тогда добавьте только то, что требуется для вашего приложения. Этот пост о микроконтейнерах покажет вам, как создать очень маленькую базу изображений на Alpine.
ОБНОВЛЕНИЕ: официальные изображения Docker теперь основаны на альпийском, так что теперь их удобно использовать.
источник
Вот еще несколько вещей, которые вы можете сделать :
RUN
команд, где вы можете. Положите как можно больше в однуRUN
команду (используя&&
)Благодаря этим обоим и рекомендациям @Andy и @michau я смог изменить размер своего изображения nodejs с 1,062 ГБ до 542 МБ.
Изменить: Еще одна важная вещь: «Мне потребовалось некоторое время, чтобы понять, что каждая команда Dockerfile создает новый контейнер с дельтами. [...] Не имеет значения, если вы rm -rf файлы в более поздней команде; они продолжают существовать в каком-то контейнере промежуточного слоя ". Так что теперь мне удалось поставить
apt-get install
,wget
,npm install
(с GIT зависимостей) иapt-get remove
в однойRUN
команде, так что теперь мое изображение имеет только 438 МБ.Изменить 29/06/17
С Docker v17.06 появились новые функции для Dockerfiles: вы можете иметь несколько
FROM
операторов в одном Dockerfile, и только последний материалFROM
будет в вашем окончательном образе Docker. Это полезно для уменьшения размера изображения, например:В результате изображение будет иметь только базовое изображение nodejs плюс содержимое из / var / my-project с первых шагов - но без ruby, python, git, openssh и gcc!
источник
Да, эти размеры смешны, и я действительно не знаю, почему так мало людей это замечают.
Я сделал образ Ubuntu, который на самом деле минимален (в отличие от других так называемых «минимальных» изображений). Он называется
textlab/ubuntu-essential
и имеет 60 МБ.Изображение выше 82 МБ после установки nano.
У Git гораздо больше предпосылок, поэтому размер изображения увеличивается, около 192 МБ. Это еще меньше, чем первоначальный размер большинства изображений.
Вы также можете взглянуть на сценарий, который я написал, чтобы создать минимальный образ Ubuntu для Docker . Возможно, вы можете адаптировать его для Fedora, но я не уверен, сколько вы сможете удалить.
источник
Следующее мне очень помогло:
После удаления неиспользуемых пакетов (например, redis 1200 mb освобождается) из моего контейнера, я сделал следующее:
Слои становятся плоскими. Размер нового изображения будет меньше, потому что я удалил пакеты из контейнера, как указано выше.
Потребовалось много времени, чтобы понять это, и поэтому я добавил свой комментарий.
источник
docker export <CONTAINER ID> | docker import - some-image-name:latest
Для лучшей практики вы должны выполнить одну команду RUN, потому что каждая инструкция RUN в Dockerfile записывает новый слой в образ, и каждый слой требует дополнительного места на диске. Чтобы свести к минимуму количество слоев, любые манипуляции с файлами, такие как установка, перемещение, извлечение, удаление и т. Д., В идеале должны выполняться в одной инструкции RUN.
источник
Docker Squash - действительно хорошее решение для этого. Вы можете
$packagemanager clean
на последнем шаге вместо каждой строки, а затем просто запустить сквош докера, чтобы избавиться от всех слоев.https://github.com/jwilder/docker-squash
источник
Да, система слоев довольно удивительна. Если у вас есть базовое изображение, и вы увеличиваете его, выполняя следующие действия:
Изображение имеет точно такой же размер. По сути, это означает, что вам нужно уметь вкладывать в свои шаги RUN много магии извлечения, установки и очистки, чтобы сделать изображения такими же маленькими, как и установленное программное обеспечение.
Это делает жизнь намного сложнее ...
В dockerBuild отсутствуют шаги RUN без коммита.
источник