📜 ⬆️ ⬇️

Elixir: Deploying Applications with Edeliver


We have already discussed building and deploying Elixir applications ( translated: using exrm ): how to migrate over a release or how to work with environment variables . It's time to discover another tool that will help you deploy Elixir applications.


The practice of deploying Elixir applications and further tracking their work on nodes with the help of Exrm allows us to feel much more confident in the issues of release management in production . However, the following question arises: how to manage the deployment process itself? Of course, we can use Capistrano , especially if we come to the world of Elixir from Rails . But look at the quote from Edeliver README :


edeliver is delivery based and provides a bash script for building and deploying Elixir and Erlang applications, as well as allowing for a hot code update.

Trying to organize the whole process of deployment manually is a hard headache with a bunch of repetitive code. But using Edeliver for deployment turned out to be very simple from the very first attempt! In the end, the whole deployment process fit into one small bash script:


#!/bin/bash -ex BRANCH=${1:-master}; mix edeliver build release --branch=BRANCH --verbose mix edeliver deploy release to production --verbose mix edeliver start production --verbose mix edeliver migrate production up --verbose 

Most likely you will have to tweak this script for your own needs. We use it only for deployment in production , but you can also use it for staging deployments. Description of how it all works - under the cut.


How it works


As we saw in the README, Edeliver works mainly with bash scripts. Mix commands are executed using Elixir , but in fact they run bash scripts. Some terminal instructions are executed locally: they create new instructions that will be executed on remote servers via RPC .
Let's delve into some aspects of the library.


Environment


Edeliver is a great opportunity to launch and deliver releases to various environments. The concept of environments is simple: build , stage and production . Everything is clear, except that the build environment has some nuances.


In order for a release to run safely on a production server, it must be compiled on a machine with the same architecture. The thing is, Edeliver uses Exrm to build releases. Exrm will use its NIFs (these are functions written in C for Erlang ), which may vary depending on the architecture of the machine, so, for example, a release compiled on OSX may not work on Linux. You can read more about this here in Phoenix , where people discuss cross-compilation issues and all sorts of other Exrm fetters .


In short, to use the build environment on our developer machine, it must have the same architecture as on the staging and production machines. Otherwise it will not work.


To configure our environments, you need to create a .deliver folder in our project and add a configuration file. Let's see what the authors of Edeliver advise us to write into it:


 #!/usr/bin/env bash APP="your-erlang-app" # name of your release BUILD_HOST="build-system.acme.org" # host where to build the release BUILD_USER="build" # local user at build host BUILD_AT="/tmp/erlang/my-app/builds" # build directory on build host STAGING_HOSTS="test1.acme.org test2.acme.org" # staging / test hosts separated by space STAGING_USER="test" # local user at staging hosts TEST_AT="/test/my-erlang-app" # deploy directory on staging hosts. default is DELIVER_TO PRODUCTION_HOSTS="deploy1.acme.org deploy2.acme.org" # deploy / production hosts separated by space PRODUCTION_USER="production" # local user at deploy hosts DELIVER_TO="/opt/my-erlang-app" # deploy directory on production hosts 

In general, everything is simple and transparent, you just need to make sure that ssh access to all listed servers is available. An additional feature is that, as it was already burning, it is quite possible to launch releases on several servers.


How can I add additional tasks for my deployment processes?


Edeliver does the standard only common things for all Elixir or Erlang applications. But if, for example, we use Phoenix , we need to run a couple more commands before we generate a release. The most important are


 $ branch build --production 

and


 $ mix phoenix.digest 

for statics to work in our releases.


To do this, define a hook in our .deliver/config file:


 pre_erlang_clean_compile() { status "Preparing assets with: brunch build and phoenix.digest" __sync_remote " # runs the commands on the build host [ -f ~/.profile ] && source ~/.profile # load profile (optional) # fail if any command fails (recommended) set -e # enter the build directory on the build host (required) cd '$BUILD_AT' mkdir -p priv/static # required by the phoenix.digest task # installing npm dependencies npm install # building brunch brunch build --production # run your custom task APP='$APP' MIX_ENV='$TARGET_MIX_ENV' $MIX_CMD phoenix.digest $SILENCE " } 

The code above was brazenly torn from the documentation for Edeliver , which explains how to work with hooks, and for some reason immediately earned.


What about my environment variables?


We have already told how to behave correctly with environment variables so as not to export them to the build environment here , and it still works! However, something else must be borne in mind.


To be able to change the environment, you must add RELX_REPLACE_OS_VARS=true before our launch command. But this is not possible in Edeliver , because the first command is executed locally:


 $ mix edeliver start production 

Therefore, a possible solution is to export RELX_REPLACE_OS_VARS to your production environment.


Before the start


It seems that Edeliver is a cool thing to manage releases and the deployment process in general. It seemed to me very easy to use. In this article, I did not delve into the insides of her work, so read the README and all sorts of docks - everything is very well written there.


I deploy so, and how are you? Write in the comments!


')

Source: https://habr.com/ru/post/305564/


All Articles