- PVSM.RU - https://www.pvsm.ru -

Деплой Elixir-приложений

Deploy Exilir Applications

Данная статья участвует в конкурсе от Wunsh.ru [1] — русскоязычное сообщество Elixir. Практики и просто сочувствующие — присоединяйтесь [2]!

В статье рассмотрен процесс настройки приложения для релиза на удалённый сервер. Для такого не лёгкого дела в мире Elixir существует два хороших проекта, первый это Distillery, которой делает билд приложения и второй это Edeliver, которой позволяет осуществлять горячую замену кода. Ниже приведены базовые инструкции по использованию этих двух библиотек на примере простейшего Elixir-приложения. А также статья расскажет каким образом можно улучшить деплой благодаря использованию docker контейнеров.

Distillery

Distillery предназначен для автоматизации генерации релизов Elixir проектов! Является наследником Exrm [3] от того же автора. Очень прост в использовании.

Первым делом необходимо добавить 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 имеет большое кол-во настраиваемых параметров [4]. Файл, сгенерированный автоматически, сразу же подошёл.

Для того, чтобы сделать билд приложения для развёртывания в "боевом" режиме, необходимо выполнить следующую команду:

MIX_ENV=prod mix release --env=prod

Данная команда создаст архив _build/prod/rel/<name>/releases/<version>/<name>.tar.gz с собранным приложением. Далее этот архив необходимо доставить на прод. сервер, где потребуется разархивировать и запустить приложение. Это возможно сделать с помощью простенького shell скрипта, но это не лучший вариант, так как будет downtime.

deploy.sh

#!/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 скриптов [5], которая умеет собирать и развёртывать 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 [6] вот этой статьи http://teamon.eu/2017/deploying-phoenix-to-production-using-docker/ [7]

Heroku

Деплой Elixir приложений на Heroku очень прост, всё что нужно, так это добавить билдпак к уже существующему приложению

heroku buildpacks:set https://github.com/HashNuke/heroku-buildpack-elixir

Или создать новое приложение с указанием данного билдпака.

heroku create --buildpack "https://github.com/HashNuke/heroku-buildpack-elixir.git"

Данный билдпак может быть сконфигурирован по примеру из официально репозитория [8].

Затем всё как вы привыкли, просто выполните:

git push heroku master

Заключение

Если вам интересен функциональный язык программирования Elixir или вы просто сочувствующий то советую вам присоединиться к Telegram-каналу https://telegram.me/proelixir [9] про Elixir.

У отечественного Elixir сообщества начинает появляться единая площадка в лице проекта Wunsh.ru [1]. Сейчас у проекта есть тематическая рассылка, в которой нет ничего нелегального, раз в недельку будет приходить письмо с подборкой статей про Elixir на русском языке.

Литература

http://bitwalker.org/posts/2016-07-21-distillery-vs-exrm-vs-relx/ [10]
https://shovik.com/blog/6-deploying-phoenix-apps-for-rails-developers [11]
https://github.com/bitwalker/distillery [12]
https://github.com/boldpoker/edeliver [13]
https://github.com/HashNuke/heroku-buildpack-elixir [14]
http://blog.plataformatec.com.br/2016/06/deploying-elixir-applications-with-edeliver/ [15]

Автор: Folklore

Источник [16]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/deploy/242022

Ссылки в тексте:

[1] Wunsh.ru: http://wunsh.ru

[2] присоединяйтесь: http://wunsh.ru/news/2016/first-contest.html

[3] Exrm: https://github.com/bitwalker/exrm

[4] настраиваемых параметров: https://hexdocs.pm/distillery/configuration.html

[5] набором bash скриптов: https://github.com/gerhard/deliver

[6] перевод от Wunsh: https://wunsh.ru/articles/elixir-deploy-1.html

[7] http://teamon.eu/2017/deploying-phoenix-to-production-using-docker/: http://teamon.eu/2017/deploying-phoenix-to-production-using-docker/

[8] официально репозитория: https://github.com/HashNuke/heroku-buildpack-elixir#configuration

[9] https://telegram.me/proelixir: https://telegram.me/proelixir

[10] http://bitwalker.org/posts/2016-07-21-distillery-vs-exrm-vs-relx/: http://bitwalker.org/posts/2016-07-21-distillery-vs-exrm-vs-relx/

[11] https://shovik.com/blog/6-deploying-phoenix-apps-for-rails-developers: https://shovik.com/blog/6-deploying-phoenix-apps-for-rails-developers

[12] https://github.com/bitwalker/distillery: https://github.com/bitwalker/distillery

[13] https://github.com/boldpoker/edeliver: https://github.com/boldpoker/edeliver

[14] https://github.com/HashNuke/heroku-buildpack-elixir: https://github.com/HashNuke/heroku-buildpack-elixir

[15] http://blog.plataformatec.com.br/2016/06/deploying-elixir-applications-with-edeliver/: http://blog.plataformatec.com.br/2016/06/deploying-elixir-applications-with-edeliver/

[16] Источник: https://habrahabr.ru/post/320096/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best