Рубрики
Uncategorized

Docker Build `—replace`

В этой статье охватывает «Docker Build заменить», сценарий, который я использую в проектах, которые содержат DockerFiles, … Теги с докером, дежоптом.

Эта статья охватывает «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»