В Докер для процесса сборки Я представил идею извлечения фазы сборки проекта в специальную build_img.sh
Сценарий, который использует соединительную среду Bonterised Build для создания изображения «Запустить» для проекта, что позволяет создавать проект на среде хозяина без установки каких-либо дополнительных инструментов, отличных от Docker. В этом посту я буду расширяться по этой идее и показать, как мы можем использовать этот сценарий в качестве основы для нового, многоразового сценария, который позволяет нам легко работать с средой сборки нашего проекта.
Основное использование
Идея здесь состоит в том, чтобы создать с_build_env.sh
Скрипт, который, по его наиболее простому, приведет к команде и запустить его в среде сборки, причем локальный каталог проекта также установлен в этой среде сборки. Это означает, что мы могли бы, например, запустить Сценарии Bash/with_build_env.sh make
даже даже установка сделать
Локально, но есть все артефакты, выводят в наш локальный каталог проекта.
Нежилое использование
Первый способ, которым этот скрипт может быть запущен — это «безголовый» способ, который является подходом, который будет в основном используется в построенном конвейере. Это запускает команду в среде сборки:
bash scripts/with_build_env.sh make posts
Более сложные команды, связанные с операторами Bash, также могут быть выполнены с использованием таких подобных Bash -c
:
bash scripts/with_build_env.sh bash -c 'make check && make posts'
Интерактивное использование
Второй способ, которым этот скрипт может быть запущен — это «интерактивный» способ, которым будет использоваться только локально в целом. Обычно это включает в себя управление интерактивной оболочкой в среде сборки. Это позволит вам запустить инструменты построения окружающей среды на вашем проекте, даже если они не установлены в местной среде.
Этот подход обычно проводится с использованием Sh
/ Bash
В качестве команды, и используя флаг, чтобы указать, что текущая команда должна работать в интерактивном режиме:
bash scripts/with_build_env.sh --dev bash
Это запускает процесс Bash в среде сборки. Это позволяет работать в вашем локальном каталоге, но используйте инструменты из вашей среды сборки.
Причина использования флага для различения интерактивного использования от беспокойного использования в том, что построение трубопроводов обычно не обеспечивают определенный механизм (TTY) для интерактивного использования, поэтому попытка запуска команды в интерактивном режиме в поле «Создание» не удалось.
Основная реализация
Ниже приведен Основные с_build_env.sh
Сценарий на основе представленных идей в Докер для процесса сборки :
org='ezanmoto' proj='hello' build_img="$org/$proj.build" bash scripts/docker_rbuild.sh \ "$build_img" \ "latest" \ --file='build.Dockerfile' \ . workdir='/go/src/github.com/ezanmoto/hello' docker run \ --rm \ --mount="type=bind,src=$(pwd),dst=$workdir" \ --workdir="$workdir" \ "$build_img:latest" \ "$@"
Это просто выполняет два действия: он восстановит изображение для среды сборки, при необходимости, а затем запускает предоставленную команду в среде сборки. Восстановление изображения не нужен, если вы используете удаленный образ, но этот шаг полезен для сохранения вашего изображения в современном виде, если ваш проект определяет свою собственную среду сборки, так как это распространено для требований проектов, которые будут расти за пределами Базовые изображения довольно быстро.
Используя этот скрипт для создания текущего проекта, затем может быть так же просто, как Сценарии Bash/with_build_env.sh make
Отказ Тем не менее, существует ряд недостатков скрипта, так как в настоящее время он такой, как тот факт, что сбор на сборку как root
и зависимости не кэшируются. Следующие разделы показывают необязательные, дополнительные шаги, которые могут быть использованы для улучшения этой базовой реализации.
Одна дополнительная заметка о with_build_env.sh
Это то, хотя общая идея и подход каждого экземпляра сценария одинаковы, каждый конкретный экземпляр сценария может варьироваться. Это связано с тем, что утилита этого скрипта обычно изменяется от проекта на проект и язык на язык. Например, когда с_build_env.sh
Сценарий хочет сохранить кеш сборки между Docker Run, специфики откуда кэш жизни обрабатываются непосредственно по с_build_env.sh
Скрипт, и это изменение в зависимости от языка и создания используемых инструментов.
Слои
Основной с_build_env.sh
Представленный выше скрипт дает много преимуществ, рекламируемых в Докер для процесса сборки прямо из коробки. Тем не менее, вы, вероятно, столкнулись с разными проблемами в зависимости от именно то, как вы будете использовать скрипт. Например, первый выпуск, который, вероятно, будет встречен при работе с этим скриптом, заключается в том, чтобы попытаться выполнить его в конвейере сборки, что, вероятно, приведет к неспособности Docker с выходом ошибок Устройство ввода не является TTY
Отказ Еще одна проблема заключается в том, что выданная команда работает root
По умолчанию, в то время как не обязательно проблема в и сам по себе может вызвать небольшое трение, когда файлы, созданные в среде сборки, принадлежат root
В каталоге хоста. В этом разделе описываются наиболее распространенные и проблемные проблемы, которые могут быть встречены вместе с возможными резолюциями.
Интерактивное использование
Первый вопрос, который часто встречается при работе с с_build_env.sh
Сценарий — это тот факт, что Docker понадобится --interactive
и --Тти
Флаги при прохождении локально, но понадобится их удаление при работе в конвейере сборки. Для этого я вообще представляю некоторые основные аргументы, разбирающиеся в скрипт, чтобы позволить ему либо работать в режиме «DEV» (Interactive) или нет:
+docker_flags='' +case "$1" in + --dev) + docker_flags="$docker_flags --interactive --tty --publish=$2" + shift 2 + ;; +esac + org='ezanmoto' proj='hello' build_img="$org/$proj.build" bash scripts/docker_rbuild.sh \ "$build_img" \ "latest" \ --file='build.Dockerfile' \ . workdir='/go/src/github.com/ezanmoto/hello' docker run \ + $docker_flags \ --rm \ --mount="type=bind,src=$(pwd),dst=$workdir" \ --workdir="$workdir" \ "$build_img:latest" \ "$@"
Прохождение --interactive
и --Тти
Достаточно для обеспечения этой функциональности, но у меня есть конвенция о том, что имея --dev
Опция Возьмите аргумент переадресации порта, который используется для выставления порта из контейнера. Это потому, что я часто нахожусь, используя порты для достижения некоторого уровня связи между хостом и контейнером, таким как запуск главного обслуживания, я работаю в среде сборки и доступа к нему от хоста. Это добавление означает, что команда для запуска интерактивной Bash Shell должна быть слегка модифицирована, но это также означает, что мы избегаем, чтобы перезапустить сеанс, чтобы разоблачить контейнер к хосту:
bash scripts/with_build_env.sh --dev 3000:3000 bash
Показатель пользователя
Это не так много проблем в конвейере сборки, но при использовании с_build_env.sh
Сценарий Как представлено выше, одна проблема заключается в том, что пользователь по умолчанию в среде сборки — корень
. Это нормально в функциональном смысле — вы, как правило, сможете создать проект без проблем и не будут работать на проблемы владения. Тем не менее, он быстро становится очень утомительным от перспективы использования возможности использования — любые файлы, созданные в контейнере, принадлежат root
, требуется Sudo
Чтобы удалить их локально, и случайно выполнял Гит
Операции могут привести к боли по линии как некоторые файлы в вашем озвучивать
каталог может иметь измененную собственность.
Как более удобное решение, которое я обычно пропускаю --user = "$ (удостоверение личности): $ (ID - Group)"
к команде Docker Run. Это означает, что мы сейчас работаем в качестве нашего пользователя Host при использовании среды сборки, поэтому любые файлы, которые мы создаем, будет иметь желаемое владение:
docker run \ $docker_flags \ --rm \ + --user="$(id --user):$(id --group)" \ --mount="type=bind,src=$(pwd),dst=$workdir" \ --workdir="$workdir" \ "$build_img:latest" \ "$@"
Пользовательские сопоставления предостережения
Одной из проблем с отображением пользователей, как представленное, в том, что, хотя мы используем правильные идентификаторы пользователя и группы в контейнере для локального развития, этот пользователь на самом деле не существует в среде сборки. Это означает, что любые инструменты, которые полагаются на $ Главная
, в том числе многие команды Git и SSH, просто не будут работать. Такие команды будут иметь либо необходимо запускать внешнюю среду сборки (например,
GIT Commitse ), или иначе среда сборки необходимо будет настроить с помощью функционального пользователя для выполнения определенных команд с
Sudo. . Чтобы пользователю не всегда необходимо существовать в контейнере, но если это тогда Этот пользователь может быть создан в среде сборки с желаемым идентификатором пользователя и идентификатором группы
Кэширование
Конвенция с_build_env.sh
это --rm
Контейнеры после каждого использования, что полезно для того, чтобы избежать случайного в зависимости от эфемерных аспектов среды сборки. Однако это означает, что любые проектные зависимости, хранящиеся за пределами каталога проекта, должны быть перезагружены с каждым запуском среды сборки.
Решение для этого — кэшировать загруженные файлы. Это большая область, где скрипт будет изменяться на основе языка программирования и используемой инструментации.
Первым шагом является создание области, чтобы сохранить кэшированные каталоги. Для этого я создаю названные тома с открытыми разрешениями:
tmp_cache="$org.$proj.tmp_cache" pkg_cache="$org.$proj.pkg_cache" tmp_cache_dir='/tmp/cache' pkg_cache_dir='/go/pkg' docker run \ --rm \ --mount="type=volume,src=$tmp_cache,dst=$tmp_cache_dir" \ --mount="type=volume,src=$pkg_cache,dst=$pkg_cache_dir" \ "$build_img:latest" \ chmod \ 0777 \ "$tmp_cache_dir" \ "$pkg_cache_dir"
Специфическое использование изображений здесь не важно (ему просто нужно иметь Chmod
настоящий) Но мы используем среду сборки для простоты. Мы даем каталог открытых разрешений, потому что объемы принадлежат root
При создании Docker, и мы хотим позволить любому пользователю иметь возможность загружать зависимости и выполнять сборки в среде сборки.
Также полезно префикс название тома с именем проекта ( ezanmoto.hello.
В этом примере), чтобы помочь изолировать строить по границам проекта. См. Раздел «Предостережения» ниже, для получения более подробной информации.
Последний кусок головоломки затем должен установить громкость при использовании среды сборки, и чтобы инструменты сборки мы используем, знаете об этом:
docker run \ $docker_flags \ --rm \ + --env=XDG_CACHE_HOME="$tmp_cache_dir" \ + --mount="type=volume,src=$tmp_cache,dst=$tmp_cache_dir" \ + --mount="type=volume,src=$pkg_cache,dst=$pkg_cache_dir" \ --user="$(id --user):$(id --group)" \ --mount="type=bind,src=$(pwd),dst=$workdir" \ --workdir="$workdir" \ "$build_img:latest" \ "$@"
Мы можем видеть, что инструменты Go Build рассказывают о каталоге кэша с помощью использования Xdg_cache_home
Переменная среды.
Эта настройка позволяет постоянством проектных зависимостей по всему Docker Run
S, не выпекая их на изображение и не хранить их на месте. Кэш также может быть очищен бегом Docker Volume RM Ezanmoto.hello.tmp_cache ezanmoto.hello.pkg_cache.
и область кэша будет автоматически перейдет в следующий раз с_build_env.sh
бежит.
Ржавчина
Ниже показано, как аналогичный механизм кэширования может быть реализован для ржавчины. Этот фрагмент взят из другого проекта моего:
docker run \ --rm \ --mount='type=volume,src=dpnd_cargo_cache,dst=/cargo' \ "$build_img:latest" \ chmod 0777 /cargo docker run \ --interactive \ --tty \ --rm \ --mount='type=volume,src=dpnd_cargo_cache,dst=/cargo' \ --env='CARGO_HOME=/cargo' \ --user="$(id -u):$(id -g)" \ --mount="type=bind,src=$(pwd),dst=/app" \ --workdir='/app' \ "$build_img:latest" \ "$@"
Видно, что ржавчина использует Cargo_home
Переменная среды, чтобы найти кеш.
Предостережения объемов кэша
Как правило, должно быть хорошо, чтобы использовать один и тот же кеш по всему проектам, но некоторые инструменты могут столкнуться с трудностями, когда один и тот же объем кэширования совместно используется между проектами (я испытал это при использовании в частности, где я столкнулся с проблемами с контрольной базой помощью ).
Самое простое решение в этом сценарии состоит в том, чтобы префиксировать имя громкости с именем проекта, чтобы изолировать объемы на проект. Однако отметим, что эта проблема все еще может возникнуть даже в одном проекте, например, при изменении между ветвями с различными блокировками. В этом сценарии полезно удалить объем кэша и разрешить с_build_env.sh
Чтобы воссоздать это:
docker volume rm ezanmoto.hello.tmp_cache ezanmoto.hello.pkg_cache
Преимущества
Непосредственное преимущество с_build_env.sh
Это то, что предположить, что прямой дочерний доступ доступа к нам в конвейере сборки, мы можем использовать те же команды локально, которые используются в конвейере сборки. Это облегчает настройку нашего трубопровода, но также означает, что мы можем запустить наш локальный код в среде сборки, прежде чем мы примите участие в том, чтобы помочь обеспечить, чтобы код, который основан на местном уровне, также построит в строительстве.
Некоторые другие преимущества:
У нас есть более простой механизм, чтобы открыть оболочку в среде сборки, которая может использоваться для строительства, тестирования и отладки.
Мы можем легче работать с проектом без необходимости вручную устанавливать свои зависимости и необходимые инструменты, что помогает нам избежать проблем при первом запуске проекта. Это особенно полезно для бортовых новых разработчиков.
Многие из преимуществ, изложенных в Докер для процесса сборки Также применить. В частности, теперь сейчас становится намного проще начать интерактивную среду сборки.
Заключение
с_build_env.sh
Скрипт позволяет нам абстрактным процессом запущенных команд в среде сборки, что облегчает нами для создания, выполнения и кода отладки в реплицированной среде сборки. Это позволяет большего четности с конвейером постройки и дальше помогает избежать классической «это работает на моей машине».
Эта статья была изначально Опубликовано на Seankelleher.ie Отказ
Оригинал: «https://dev.to/smortimerk/docker-withbuildenv-sh-script-4o9a»