GrabDuck

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

:

Deploy Exilir Applications

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

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


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.


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 — по сути своей написанная на 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

Здесь мне нечего рассказать, лучше прочтите отличный перевод от Wunsh вот этой статьи http://teamon.eu/2017/deploying-phoenix-to-production-using-docker/


Деплой 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/