Dev & EngARTIGO

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/

 

Como um desenvolvedor de software, Igor encontrou na comunidade Ruby um caminho para a felicidade profissional por conta do "Ruby way". Hoje, tem dividido sua atenção também com a comunidade Elixir, que consegue transmitir o mesmo entusiasmo que teve quando iniciou a jornada em Ruby. Ele está sempre pensando em melhorias e trabalha com Ruby on Rails e metodologias ágeis na Plataformatec.

Ver perfil →
Leia também