второму этапу сборки.
Начало второго этапа сборки начинается с использования в качестве базовой последней версии Alpine. Поскольку двоичный файл является статическим, мы могли бы использовать царапину в качестве основы. Тем не менее, мне нравится использовать Alpine, поскольку он уже имеет довольно минимальный размер, но также предоставляет вам менеджер пакетов на случай, если вам все еще понадобится какое-то подмножество зависимостей, что в большинстве случаев вам понадобится.
Здесь мы должны снова установить наш WORKDIR
и скопировать в него двоичный файл. Команда COPY
имеет параметр --from
, который позволяет указать, какой этап сборки следует использовать в качестве источника. В этом случае мы можем ссылаться на псевдоним builder
, который мы определили на первом этапе. Наконец, мы должны установить точку входа изображения в наш двоичный файл, чтобы любые аргументы, передаваемые в изображение, пересылались в сам двоичный файл внутри контейнера.
Теперь, когда мы определили наш Dockerfile, нам нужно создать с его помощью образ. Мы можем сделать это, запустив docker build -t greeter .
. Это создаст изображение с тегом Greeter, которое мы затем сможем запустить с помощью docker run --rm greeter --shout George
. Поскольку мы определили точку входа изображения в двоичный файл, это будет идентично запуску ./greeter --shout George
с локальной копией двоичного файла.
Опция --rm
удалит контейнер после его выхода, что полезно при однократных вызовах, чтобы они не накапливались.
Также возможно извлечь двоичный файл из контейнера. Но прежде чем мы сможем это сделать, нам нужно получить идентификатор контейнера. Вы можете просмотреть существующие контейнеры с помощью команды docker ps -a
. Если вы запустите наш образ без флага --rm
, вы увидите вышедший из этого вызова контейнер. Если у вас в настоящее время нет существующего контейнера, его можно создать с помощью команды docker create greetinger
, которая возвращает идентификатор контейнера, который мы можем использовать на следующем шаге.
Docker также предоставляет команду cp
, которую можно использовать для извлечения файла из контейнера. Например, чтобы извлечь двоичный файл greeter в текущую папку, используйте команду docker cp abc123:/greeter ./
, где вам следует заменить abc123
идентификатором контейнера, из которого следует извлечь файл.
Даже если ваш проект предназначен для внутреннего использования, Docker все равно может быть хорошим инструментом для организации развертываний, поскольку каждая версия проекта существует в своем собственном образе. Это позволяет различным инструментам, таким как Kubernetes, легко масштабировать и развертывать после их настройки.
Через менеджер(ы) пакетов
Другой способ распространения двоичного файла — добавить его в выбранные вами менеджеры пакетов. Хотя описание того, как это сделать, немного выходит за рамки этой книги, стоит упомянуть, что это может значительно улучшить пользовательский опыт (UX), поскольку пользователь может устанавливать/обновлять ваш проект точно так же, как они делают остальные пакеты. Некоторые распространенные менеджеры пакетов, которые можно использовать, включают следующее:
• Snap
• macOS's Homebrew
• Arch Linux's AUR
В конечном счете, это необязательный шаг. Предоставления предварительно собранного двоичного файла и инструкций по сборке из исходного кода, скорее всего, будет достаточно для начала.
Благодаря единственному двоичному файлу и переносимости двоичных файлов Crystal развертывание приложения, по сути, так же просто, как копирование двоичного файла куда-либо и его запуск. Нет необходимости включать исходный код или исключать непроизводственные файлы в процесс сборки, поскольку все это делается за вас, когда используются правильные параметры.
Однако, несмотря на то, что этот процесс относительно прост, в сочетании с выполнением тестов и созданием документации, требуется выполнить довольно много шагов, которые через некоторое время могут стать утомительными для выполнения вручную каждый раз, когда новая версия готова к выпуску. В следующей и заключительной главе мы рассмотрим, как автоматизировать некоторые из этих процессов.
Существует гораздо больше материалов, связанных с развертыванием проектов, чем мы можем охватить в этой главе. Ознакомьтесь со следующими ссылками для получения дополнительной информации по темам, которые мы рассмотрели:
• https://crystal-lang.org/reference/guides/static_linking. html
• https://docs.docker.com/develop/develop-images/baseimages
• montreal.html
Поздравляем с тем, что вы зашли так далеко! Мы рассмотрели многое, но, увы, дошли до последней главы. В нескольких предыдущих главах мы рассмотрели, как превратить работающий проект в полностью пригодный для использования и простой в обслуживании путем написания тестов, документирования того, как он работает, и распространения его среди конечных пользователей. Однако можно легко забыть выполнить один или несколько из этих шагов, что сведет на нет всю цель. В этой главе мы собираемся изучить, как автоматизировать эти процессы, а также несколько новых, чтобы вам вообще о них не приходилось думать! При этом мы собираемся охватить следующие темы:
• Код форматирования.
• Линтинг-код
• Непрерывная интеграция с GitHub Actions.
Требования к этой главе следующие:
• Рабочая установка Crystal.
• Специальный репозиторий GitHub.
Вы можете обратиться к Главе 1 «Введение в Crystal» для получения инструкций по настройке Crystal, а также к https://docs.github.com/en/get-started/quickstart/create-a-repo для настройки вашего репозитория.
Все примеры кода, использованные в этой главе, можно найти в папке Chapter17 на GitHub: https://github.com/PacktPublishing/Crystal-Programming/tree/main/Chapter17.
Некоторые из самых горячих споров в программировании могут возникать из-за самых незначительных вещей, например, следует ли использовать табуляции или пробелы для отступов или сколько каждого из них. Crystal пытается предотвратить возникновение подобных сценариев, предоставляя стандартизированный, осуществимый стиль кода, который следует использовать в каждом проекте.
Вот некоторые примеры того, что делает форматтер:
• Удаляет лишние пробелы в конце строк.
• Отменить экранирование символов, которые не нужно экранировать, например Foo
и Foo
.
• При необходимости добавляет/удаляет отступы, включая замену ;
с символами новой строки в некоторых случаях.
Хотя не все могут согласиться со всем, что делает форматтер, в этом-то и суть. Он предназначен для обеспечения стандарта, а не для настройки с целью исключения выбора из уравнения. Однако это не означает, что нет областей, которые можно улучшить, или случаев неправильного форматирования.
Этот стиль кода обеспечивается командой Crystal, очень похожей на команды spec
, run
или build
, которые мы использовали в предыдущих главах. Самый простой способ использовать форматтер — run crystal tool format
в вашей кодовой базе. При этом будет просмотрен каждый исходный файл и отформатирован его в соответствии со стандартом Crystal. Некоторые IDE даже поддерживают форматтер и запускают его автоматически при сохранении. См. Приложение A «Настройка инструментов» для получения более подробной