Back-End

24 jul, 2014

Gerenciando o ambiente do seu projeto com Foreman e Dotenv

Publicidade

foreman

Nenhuma aplicação costuma ser igual. Geralmente, cada uma tem sua particularidade quando se trata de utilização de serviços. Se você tem a sorte de sempre pegar projetos onde utiliza um simples serviço de banco de dados, agradeça muito. Hoje em dia, com a evolução da tecnologia para desenvolvimento de aplicações, podemos contar com vários tipos de serviço, como banco de dados, background job, cron, redis, elasticsearch, guard etc. Fazer todos os serviços rodarem ao mesmo tempo pode fazer com que você tenha um monte de abas abertas no terminal, pois alguns serviços necessitam utilização da sessão do terminal continuamente.

Se você está utilizando um Mac, por exemplo, provavelmente você usou Homebrew ou MacPorts para instalar as dependências do seu projeto. No fim você executou algo como:

ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents

No exemplo acima estou fazendo com que o serviço do Postgre seja iniciado juntamente com o sistema operacional. Não, pera! Pense um pouco sobre isso. Você vai rodar esse serviço a todo momento que seu sistema operacional iniciar. Se você tem alguma aplicação rodando a todo momento no seu sistema, pode até fazer sentido. Se isso não for o caso, por qual motivo você estaria fazendo isso, se não é realmente necessário?

David Dollar percebeu que suas aplicações ficaram cada vez mais complicadas de serem executadas. Isso resultou, então, na criação de uma gem chamada Foreman, que nada mais é do que um gestor de aplicações baseado em Procfile. Seu objetivo é abstrair a quantidade de serviços que deveriam estar rodando para que sua aplicação funcione em um único local. Sendo assim, ao invés de ter serviços desnecessários rodando em background, ou aplicações que necessitam ser executadas em várias abas do terminal para que sua aplicação funcione, você apenas agrupa e starta o necessário para sua aplicação funcionar em um único local.

Use onde quiser!

befree

Apesar do Foreman ser uma gem e a maioria dos desenvolvedores utilizar em aplicações ruby, isso não significa que necessariamente você precisa usar com ruby. Você pode rodar qualquer coisa que possa ser chamada pelo terminal em forma de linha de comando. Sendo assim, você possivelmente vai poder executar dependências da sua aplicação Java, Ruby, Python, Go, Javascript (Node.js) ou outra linguagem. Realmente é uma incrível ferramente que provavelmente não deveria ficar de fora do seu ambiente de desenvolvimento.

Instalação

Para instalar o Foreman é necessário ter ruby e rubygems instalado no seu sistema operacional. Basta executar `gem install foreman` para instalar a gem no sistema. Após isso é necessário criar um arquivo Procfile, na raiz do projeto. É preciso definir uma chave para o nome do processo e o comando que deverá ser executado no terminal para a aplicação ser executada. Veja um exemplo abaixo:

redis:          redis-server config/redis/development.conf
web:            bundle exec rails s
elasticsearch:  elasticsearch -f
sidekiq:        bundle exec sidekiq -v
solr_dev:       bundle exec rake sunspot:solr:run
solr_test:      bundle exec rake sunspot:solr:run RAILS_ENV=test
worker:         bundle exec rake resque:work QUEUE=*
guard:          bundle exec guard

Agora dê uma olhada nesse código acima. Imagine cada comando desse rodando em uma aba do terminal. Bagunça, né? Ter que levantar cada serviço manualmente me daria um trabalho bem grande. Para iniciar o ambiente de desenvolvimento basta executar o comando `foreman start`.

Concorrência de processos

Uma feature interessante do Foreman é o suporte a execução de mais de um processo via concorrência. Você pode definir a quantidade de processos para cada aplicação (serviço) definida no Procfile.

Como exemplo, você pode incrementar o número de workers, fazendo com que o serviço seja executado mais vezes em concorrência. Veja o exemplo abaixo:

foreman start -c worker=2

Deploy de aplicações no Heroku e o isolamento de configurações de variáveis de ambiente com Dotenv

O Foreman é utilizado no deploy de aplicações no Heroku. Se alguma vez você já fez deployments usando Heroku, vai lembrar da utilização de variáveis de ambiente (env) para configurações específicas.

Provavelmente alguma vez você pode ter passado pela situação de definir uma chave onde você não pode subir para ambiente o versionamento do código. Vejamos um exemplo prático:

config.paperclip_defaults = {
  :storage => :s3,
  :s3_credentials => {
    :bucket => ENV['S3_BUCKET_NAME'],
    :access_key_id => ENV['AWS_ACCESS_KEY_ID'],
    :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
  }
}

No código acima estou setando algumas chaves para integração do storage S3, da Amazon, com a gem Paperclip. No Heroku, é bem trivial a configuração de uma variável de ambiente. Utilizando o Heroku toolbelt, podemos executar no terminal:

heroku config:add CONFIG_VAR_TEST=true

Na aplicação, podemos recuperar o valor da variável utilizando:

ENV['CONFIG_VAR_TEST`]

Bem fácil, né? O questionamento é, como definir variáveis de ambiente quando estamos no nosso ambiente de desenvolvimento? Para nossa felicidade, o Foreman utiliza Dotenv como dependência e facilmente você pode configurar variáveis de ambiente utilizando arquivos `.env`. Na raiz do projeto você deve criar um arquivo chamado .env definindo as variáveis da seguinte forma:

VAR_TEST=true
VAR_TEST_HELLO=false
PORT_WEB=7000

Lembre-se que o arquivo `.env` não poderá ser versionado, assim deve-se ignorar este arquivo no `.gitignore` caso esteja utilizando git. Porém, uma boa prática é utilizar um arquivo `.env.development` para que os desenvolvedores que participam do projeto possam saber quais variáveis devem ser definidas para o funcionamento adequado da aplicação.

Veja o exemplo abaixo de Procfile:

web: bundle exec rails s -p $PORT_WEB

Levando em conta que estamos querendo fazer deployment no Heroku, nem todas as configurações do ambiente de desenvolvimento podem ser as mesmas do ambiente do Heroku. Você precisa criar um novo Procfile para seu ambiente de desenvolvimento. Normalmente utilizo um Procfile.development para ambiente local e um Procfile para o Heroku. Para utilizar o Procfile alternativo, você pode utilizar o `foreman start -f Procfile.development`.