Fazendo deploy de aplicações Elixir com Edeliver
Edeliver parece ser uma boa opção para lidar com nossos releases e processos de deploy.
No blog da Plataformatec, temos falado sobre deploy e releases com Elixir↳Elixir5 conteúdosElixir programming language: Uma introdução ao Pattern MatchingDevSecOps · jan 2025Elixir programming language: Configurando o setupDevSecOps · dez 2024Go vs Elixir, primeiras impressõesDev (Back & Front) · out 2020Ver tudo em Dev (Back & Front) → ultimamente, como nos seguintes artigos: how to run migrations on top of a release e how to deal with environment variables. Agora, é hora de descobrir outra ferramenta que pode nos ajudar com o release da nossa aplicação em Elixir.
Depois de praticar deploy com Exrm, ficamos mais confortáveis sabendo que existe uma ferramenta com a qual podemos contar para o gerenciamento de releases de produção. Nossa próxima grande preocupação era como poderíamos tornar o processo de deploy mais gerenciável. Nós não conseguíamos parar de pensar em Capistrano, que normalmente usamos para nossos projetos Rails, então descobrimos Edeliver. Pela descrição do README do Edeliver:
Edeliver é focado em produção e fornece um script em bash para construir e fazer deploy de aplicações Elixir e Erlang, além de realizar atualizações hot-code.
Tentar fazer todo o processo de deploy manualmente era bem difícil, devido à existência de muitas tarefas repetitivas. Ao usar Edeliver para o nosso primeiro script/deploy, tudo ficou extremamente fácil! No final, todo o processo manual foi simplificado para:
#!/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
Você provavelmente vai precisar personalizar esse script, adaptando-o às suas necessidades. Nesse caso, estamos usando esse script apenas para deploys de produção, mas você pode personalizá-lo para servidores de teste com bastante facilidade. Vamos explicar como os ambientes de produção funcionam em seguida.
Como funciona
Como vimos antes na citação do README, o Edeliver faz praticamente tudo com scripts bash. As tarefas Mix que vimos acima serão executadas com Elixir, mas elas vão resultar em instruções de script bash. Parte das instruções é executada nos scripts localmente, que irão construir novas instruções que serão executadas remotamente via RPC (Remote procedure call).
Vamos nos aprofundar em alguns aspectos da biblioteca.
Ambientes
O edeliver é uma boa opção para lançamento e distribuição de releases em vários ambientes. Ele tem o conceito de três ambientes: desenvolvimento, teste e produção. Entre eles, apenas o ambiente de desenvolvimento deve receber um pouco mais de atenção.
Para que um release funcione em um servidor, ele deve ter sido construído em uma máquina com a mesma arquitetura, na qual o release será executado. Isso porque o Edeliver usa Exrm para construir seus releases. O Exrm usará internamente seus NIFs locais (funções C utilizadas pelo Erlang), que podem variar em uma arquitetura diferente, fazendo com que, por exemplo, um release OSX não funcione no Linux↳Linux34 conteúdosKali Linux em um Servidor VPS: como, quando e por que usar?DevSecOps · dez 2024Construindo um Windows Service ou Linux Daemon com Worker Service & .NET Core – Parte 2Dev (Back & Front) · jul 2020Criando uma WebApi utilizando .NET, Linux e VSCodeDev (Back & Front) · ago 2019Ver tudo em DevSecOps →. Você pode ler mais sobre isso nesta issue do Phoenix, onde as pessoas estão discutindo questões de compilação cruzada e há algumas outras issues de Exrm.
Para utilizar o ambiente de build em nossa própria máquina de desenvolvimento, ele precisa usar a mesma arquitetura de nossos servidores de teste e produção; caso contrário, ele não vai funcionar.
Para configurar nossos ambientes, vamos precisar criar um diretório .deliver em nosso projeto e adicionar um arquivo config. Vamos ver as configurações sugeridas no README do Edeliver para esse arquivo:
#!/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
É muito fácil configurar nossos ambientes, só precisamos ter certeza de que temos permissão ssh para esses servidores especificados. Uma coisa legal sobre toda essa configuração, como mencionado antes, é que é possível distribuir os releases em vários servidores.
Como posso incluir tarefas extras em meu processo de deploy?
O que Edeliver faz é genérico para aplicações Elixir e Erlang. Quando estamos usando Phoenix, por exemplo, é preciso executar algumas tarefas antes de gerar o release. As tarefas mais importantes são brunch build –production e mix phoenix.digest, para que possamos ter nossos ativos trabalhando em nosso release.
Para fazer isso funcionar, precisamos definir um hook em nosso arquivo .deliver/config:
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
"
}
Isso foi extraído de um doc de exemplo do Edeliver, que explica todas as possibilidades de hooks.
E as minhas variáveis de ambiente?
Nós compartilhamos uma dica sobre como lidar com variáveis de ambiente com Exrm, a fim de evitar exportá-los em nosso ambiente de desenvolvimento. No entanto, há um detalhe importante, no qual precisaremos prestar atenção.
A fim de tornar os ambientes substituíveis, precisamos definir RELX_REPLACE_OS_VARS = true antes do nosso comando start. Mas isso não é possível com Edeliver, porque a tarefa start é executada localmente.
mix edeliver start production
Então, uma possível solução é exportar RELX_REPLACE_OS_VARS em nosso ambiente de produção.
Considerações
Edeliver parece ser uma boa opção para lidar com nossos releases e processos de deploy, e eu o achei muito fácil de usar. Eu não entrei em detalhes em relação à implementação neste artigo, por isso certifique-se de ler o README e docs – eles são muito úteis e muito bem explicados.
Esta foi a solução que encontramos para facilitar nosso processo de deploy. Como você tem gerenciado seus processos? Este artigo ajudou?
***
Igor Florian faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://blog.plataformatec.com.br/2016/06/deploying-elixir-applications-with-edeliver/









Cezar Taurion
John Calistro
William Santos



