
Данная статья участвует в конкурсе от Wunsh.ru — русскоязычное сообщество Elixir. Практики и просто сочувствующие — присоединяйтесь!
В статье рассмотрен процесс настройки приложения для релиза на удалённый сервер. Для такого не лёгкого дела в мире Elixir существует два хороших проекта, первый это Distillery, которой делает билд приложения и второй это Edeliver, которой позволяет осуществлять горячую замену кода. Ниже приведены базовые инструкции по использованию этих двух библиотек на примере простейшего Elixir-приложения. А также статья расскажет каким образом можно улучшить деплой благодаря использованию docker контейнеров.
Distillery
Distillery предназначен для автоматизации генерации релизов Elixir проектов! Является наследником Exrm от того же автора. Очень прост в использовании.
Первым делом необходимо добавить distillery в зависимости проекта. А после выполнить mix deps.get.
def application do [ mod: {Single, []}, applications: [:logger, :cowboy, :plug] ] end defp deps do [{:cowboy, "~> 1.1.2"}, {:plug, "~> 1.3.0"}, {:distillery, "~> 1.0"}] end
Чтобы создать конфигурационный файл для distillery необходимо в директории проекта выполнить следующую команду:
mix release.init
Данная команда создаст rel директорию с файлом config.exs. Distillery имеет большое кол-во настраиваемых параметров. Файл, сгенерированный автоматически, сразу же подошёл.
Для того, чтобы сделать билд приложения для развёртывания в "боевом" режиме, необходимо выполнить следующую команду:
MIX_ENV=prod mix release --env=prod
Данная команда создаст архив _build/prod/rel/<name>/releases/<version>/<name>.tar.gz с собранным приложением. Далее этот архив необходимо доставить на прод. сервер, где потребуется разархивировать и запустить приложение. Это возможно сделать с помощью простенького shell скрипта, но это не лучший вариант, так как будет downtime.
#!/bin/sh REMOTE_USER="www" REMOTE_HOST="host" APP_NAME="single" APP_FOLDER="/home/$REMOTE_USER/$APP_NAME" SERVER=$REMOTE_USER@$REMOTE_HOST echo "Enter the version of the application" read VERSION if !(ssh $SERVER "[ -d $APP_FOLDER/tmp/ ]") then echo "Preparing directory structure" ssh $SERVER "mkdir -p $APP_FOLDER/tmp/" fi echo "Copying release to server in $APP_FOLDER" scp _build/prod/rel/$APP_NAME/releases/$VERSION/$APP_NAME.tar.gz $SERVER:$APP_FOLDER/tmp/ echo "Stopping the old version" ssh $SERVER "cd $APP_FOLDER && bin/$APP_NAME stop" echo "Extracting archive with release" ssh $SERVER "cd $APP_FOLDER/tmp/ && tar -xzf $APP_NAME.tar.gz -C $APP_FOLDER" echo "Running the new version" ssh $SERVER "cd $APP_FOLDER && PORT=80 bin/$APP_NAME start"
Осталось только проверить доступность предложения.
curl -i http://host HTTP/1.1 200 OK server: Cowboy date: Thu, 09 Feb 2017 11:28:08 GMT content-length: 9 cache-control: max-age=0, private, must-revalidate content-type: text/plain; charset=utf-8 Single v1
Можно упростить доставку приложения на прод. сервер используя Edeliver.
Edeliver
Edeliver — по сути своей написанная на Elixir надстройка над набором bash скриптов, которая умеет собирать и развёртывать Elixir и Erlang приложения, а также осуществлять горячее обновление кода.
Первым делом необходимо добавить edeliver в зависимости проекта. А после выполнить mix deps.get.
def application do [ mod: {Single, []}, applications: [:logger, :cowboy, :plug, :edeliver] ] end defp deps do [{:cowboy, "~> 1.1.2"}, {:plug, "~> 1.3.0"}, {:distillery, "~> 1.0"}, {:edeliver, "~> 1.4.2"}] end
Все настройки для Edeliver хранятся в файле .deliver/config. В нём можно указать разного рода окружения. Например BUILD, STAGING и PRODUCTION.
APP="single" BUILD_HOST="host" BUILD_USER="www" BUILD_AT="/home/www/single/tmp" PRODUCTION_HOSTS="host" PRODUCTION_USER="www" DELIVER_TO="/home/www/single"
Для того, чтобы сделать билд приложения для развёртывания в "боевом" режиме, необходимо выполнить следующую команду:
env MIX_ENV=prod mix edeliver build release
Затем, чтобы доставить билд на нужное окружение (в данном случае production) необходимо выполнить:
mix edeliver deploy release to production --version=0.1.0
Данная команда только лишь загрузит собранный релиз на удалённый сервер, но не запустит само приложение.
Для запуска приложения предназначена следующая командой:
mix edeliver start production
Если вы делали билд в отличном от production окружении, вы можете получить не работоспособное приложение. Это связано с тем, что при сборке приложения используются NIF'ы (native implemented functions), которые на разных машинах могут быть… разные.
Осталось только проверить доступность предложения.
curl -i http://host HTTP/1.1 200 OK server: Cowboy date: Thu, 09 Feb 2017 11:28:08 GMT content-length: 9 cache-control: max-age=0, private, must-revalidate content-type: text/plain; charset=utf-8 Single v2
Немного о Docker и Distillery
Здесь мне нечего рассказать, лучше прочтите отличный перевод от Wunsh вот этой статьи http://teamon.eu/2017/deploying-phoenix-to-production-using-docker/
Heroku
Деплой Elixir приложений на Heroku очень прост, всё что нужно, так это добавить билдпак к уже существующему приложению
heroku buildpacks:set https://github.com/HashNuke/heroku-buildpack-elixir
Или создать новое приложение с указанием данного билдпака.
heroku create --buildpack "https://github.com/HashNuke/heroku-buildpack-elixir.git"
Данный билдпак может быть сконфигурирован по примеру из официально репозитория.
Затем всё как вы привыкли, просто выполните:
git push heroku master
Заключение
Если вам интересен функциональный язык программирования Elixir или вы просто сочувствующий то советую вам присоединиться к Telegram-каналу https://telegram.me/proelixir про Elixir.
У отечественного Elixir сообщества начинает появляться единая площадка в лице проекта Wunsh.ru. Сейчас у проекта есть тематическая рассылка, в которой нет ничего нелегального, раз в недельку будет приходить письмо с подборкой статей про Elixir на русском языке.
Литература
http://bitwalker.org/posts/2016-07-21-distillery-vs-exrm-vs-relx/
https://shovik.com/blog/6-deploying-phoenix-apps-for-rails-developers
https://github.com/bitwalker/distillery
https://github.com/boldpoker/edeliver
https://github.com/HashNuke/heroku-buildpack-elixir
http://blog.plataformatec.com.br/2016/06/deploying-elixir-applications-with-edeliver/