Данная статья участвует в конкурсе от 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/