Эта статья охватывает «Docker Build Breake», скрипт, который я использую в проектах, которые содержат DockerFiles, которые стремятся помочь преодолеть некоторые из основных недостатков, которые я столкнулся с приходом при использовании DockerFiles в проекте.
Docker Build
Команда отлично подходит для того, чтобы помочь добиться воспроизводимых оснований для проектов, где в прошлом разработчики должны были полагаться на создание правильной среды вручную, чтобы получить успешную сборку. Один большой недостаток Docker Build
Однако в том, что он может быть очень дорогостоящим с точки зрения хранения при запуске его нескольких раз, поскольку каждый прогон команды, как правило, оставляет Безымянные изображения. Очистка может быть простым, но требует постоянного обрезки.
Необходимость удаления неиспользуемых изображений особенно ощущается при попытке разработки и отладки докерафилов. Попытка придумать минимальный набор инструкций, которые позволят вам запустить ваши процессы, как вы хотите, может потребоваться несколько Docker Build
бежит, даже после того, как вы сузите по объему с помощью интерактивных Docker Run
сессия. Такая последовательность вполне может потребоваться несколько докеровских изображений, чистки через ход сеанса, поскольку ваш диск постоянно подан загрузки старыми и избыточными изображениями. Это усугубляется дальше, если ваше изображение Docker использует такую команду, как Копировать./src.
, где каждое изменение вашего корневого проекта потребует нового сборки изображения.
Это где Docker Build --replace
Приходит, где Docker автоматически удаляет старое изображение с тем же тегом, когда создана новая копия, и пропускает сборку полностью, если она актуальна. Единственная проблема в том, что этот флаг в настоящее время не существует.
docker_rbuild.sh
Я написал docker_rbuild.sh
(«Докер заменить сборку»), чтобы приблизить идею Docker Build --replace
Используя кэш сборки:
# `$0` builds a docker image that replaces the docker image # ` : `, or creates it if it doesn't already exist. # # This script uses ` :cached` as a temporary tag and so may clobber # such existing images if present. if [ $# -lt 2 ] ; then echo "usage: $0 ..." >&2 exit 1 fi img_name="$1" shift tag="$1" shift docker tag "$img_name:$tag" "$img_name:cached" &>/dev/null if docker build --tag="$img_name:$tag" "$@" ; then docker rmi "$img_name:cached" &>/dev/null # We return a success code in case `rmi` failed. true else exit_code=$? docker tag "$img_name:cached" "$img_name:$tag" &>/dev/null exit $exit_code fi
Это тегает текущей копией изображения так, чтобы его можно было повторно использовать для целей кэширования, а затем отключить новую сборку. Если сборка была успешной, то версия «Cache» удалена, теоретически означает, что только последняя копия изображения, на которой вы работаете, должны присутствовать в вашей системе. Если сборка не удается, то старая тег восстанавливается. Если нет обновлений, то кэшированные слои используются для создания «нового» изображения практически мгновенно для замены старого.
С помощью этого локальные изображения автоматически «обрезаются», поскольку новые копии выпускаются, сохраняя время и дисковое пространство.
Idempotency.
Один из преимуществ docker_rbuild.sh
это тот факт, что, теперь, когда Docker Build
Не оставляйте избыточные изображения вокруг с каждой сборкой, это более практически возможно использовать его в сценариях, чтобы восстановить наши изображения, прежде чем мы запустим их. Это полезно, когда проект определяет локальные изображения, чтобы мы могли восстановить изображение, прежде чем он использован, каждый раз, когда он используется, так что мы всегда используем последнюю версию изображения без необходимости вручную обновлять его.
Примером того, где это может быть удобно, это когда вы хотите использовать внешнюю программу или проект, который использует язык, который не поддерживается вашим проектом. Например, процесс сборки содержимого этого блога использует Node.js, но рассмотрим случай, когда я хотел использовать Linter, определенную в RUBY, например MarkDownlint Отказ Одним из вариантов является добавление установки Ruby непосредственно в определение среды сборки, но это имеет несколько недостатков:
- Он добавляет установку для полного нового языка в среду сборки только для поддержки работы одной программы.
- Не понятно, с первого взгляда, что Ruby устанавливается только для поддержки одного инструмента, а для кого-то нового для проекта он может выглядеть так, как проект является комбинированным проектом Node.js/Ruby.
- Вышеуказанная точка поддается, чтобы использовать больше драгоценных камней Ruby «только потому, что это доступно, что означает, что удаление установки Ruby позже становится сложнее.
Один из способов работать вокруг этого — это инкапсулировать использование с помощью DockerFile, как MarkDownlint. Dockerfile
и скрипт, который запускает инструмент:
MarkDownlint. Dockerfile
:
FROM ruby:3.0.0-alpine3.13 RUN gem install mdl ENTRYPOINT ["mdl"]
markdownlint.sh
:
if [ $# -ne 1 ] ; then echo "usage: $0" >&2 exit 1 fi md_file="$1" proj='ezanmoto/hello' sub_img_name="markdownlint" sub_img="$proj.$sub_img_name" docker run \ --rm \ --volume="$(pwd):/app" \ --workdir='/app' \ "$sub_img" \ "$md_file"
Это касается некоторых из вышеуказанных вопросов:
- Ruby не устанавливается непосредственно в среду сборки, а это означает, что среда сборки поддерживается и опирается.
- В
MarkDownlint. Dockerfile
Установка Ruby поддерживается с программой, которую она используется для запуска, что делает ассоциацию ясной. - Весь рубиновая установка может быть легко удалена путем удаления
MarkDownlint. Dockerfile
Отказ Это может быть полезно, если мы решили заменить инструмент с другим линтом, например Это написано для Node.js Отказ Еще одна причина, по которой мы могли бы удалитьMarkDownlint. Dockerfile
Если внешний проект начинает поддерживать собственное общедоступное изображение докера, которое можно использовать вместо управления локальной версией.
Несмотря на преимущества, есть две тонкие проблемы с этой настройкой. Первый в том, что ezanmoto/blog_content.cmarkdownlint
нужно будет построить как-то до markdownlint.sh
Может быть запущен, который может быть ручным процессом, и это также будет удивительная ошибка, чтобы узнать, что изображение отсутствует для скрипта.
Второй выпуск заключается в том, что если один разработчик создает локальное изображение, а второй разработчик обновляет определение изображения, первый разработчик должен будет восстановить их копию локального изображения перед запуском markdownlint.sh
снова или риск Неожиданные результаты.
Мы можем решить оба этих вопроса, работая docker_rbuild.sh
перед запуском ezanmoto/blog_content.cmarkdownlint
:
markdownlint.sh
:
bash scripts/docker_rbuild.sh \ "$sub_img" \ 'latest' \ --file="$sub_img_name.Dockerfile" \ . docker run \ --rm \ --volume="$(pwd):/app" \ --workdir='/app' \ "$sub_img" \ "$md_file"
Это приводит к тому, что изображение всегда перестраивается до того, как он используется, означает, что мы всегда работаем с последней версией изображения, и этот шаг сборки чаще всего будет пропущен из-за кэширования (хотя внимание следует уплатить на Команды, используемые в сборке изображений, поскольку использование команд, таких как Copy
может ограничить эффективность кэша).
Использовать с Docker-Compose
Я нахожу Docker-Compose
Особенно полезно для развертывания моделирования. Однако, как развивающиеся образы докера, получая Docker-Compose
Окружающая среда может потребовать постоянной тонкой настройки докеровских изображений, особенно для определения минимальных сред. Это может еще раз привести к тому много потраченного пространства, особенно при использовании с Docker-Compose Up --Build
Отказ
С учетом этого я сейчас удаляю построить
Недвижимость от услуг, определенных в Docker-Compose.yml
Отказ Это затем требует, чтобы изображения были построены до Docker-Compose
называется, который я обычно обращаюсь в сценарии, который построит все изображения, используемые в Docker-Compose.yml
Файл до названия файла:
Docker-Compose.yml
:
version: '2.4' services: hello.seankelleher.local: image: nginx:1.19.7-alpine ports: - 8080:8080 volumes: - ./configs/hello.conf:/etc/nginx/conf.d/hello.conf:ro hello: image: ezanmoto/hello
Сценарии/Docker_compose_up_build.sh
:
set -o errexit proj='ezanmoto/hello' run_img="$proj" bash scripts/docker_rbuild.sh \ "$run_img" \ 'latest' \ . docker-compose up "$@"
Вывод
Наличие IDEMPotent Rebuild для Docker-изображений означает, что это более возможно восстановить перед каждым прогоном, так же, как и некоторые инструменты сборки (E.G. Cargo
) обновляют любые измененные зависимости перед попыткой восстановления кодовой базы. В то время как Docker не имеет народной поддержки для этого в настоящее время, сценарий, который использует преимущество кэша, может использоваться для моделирования такого поведения.
Эта статья была изначально Опубликовано на Seankelleher.ie Отказ
Оригинал: «https://dev.to/smortimerk/docker-build-replace-57gh»