MouseOver Studio

MouseOver Studio header image 2

Deploy mais simples de aplicações Rails com Inploy

outubro 9th, 2009 por Diego Carrion · 8 comentários

Após ter trabalhado em diversos sistemas feitos em Rails, trabalhar com Capistrano era uma das coisas que começou a me incomodar cada vez mais. Tentei achar outras alternativas, cheguei a dar uma olhada no Vlad, mas também não me agradou, pelo que decidi criar uma ferramenta e chamei ela de Inploy.

Antes de que os fans do Capistrano comecem a me crucificar, queria deixar claro que eu não acho o Capistrano ruim como ferramenta, somente acho ele ruim para minhas necessidades, que são bem mais simples das que o Capistrano consegue atender.

Uma da coisas que me incomoda no Capistrano é esse monte de pastas que ele cria, uma para cada release. Já argumentaram comigo que são uteis quando você quer voltar para um release velho. O problema é que eu nunca precisei voltar para um release x e a maioria de pessoas com as que falei também nunca precisaram, e talvez nunca precisarão.

Como podem ter percebido, eu falei “a maioria”. Algumas pessoas (muito poucas) me falaram que já tiveram que voltar para um release velho, mas foi porque subiram código que quebrou algumas funcionalidades e tiveram que dar rollback enquanto corregiam o erro.

De qualquer jeito, o Inploy utiliza Git, pelo que se precisamos voltar a uma versão x, é só dar um reset. Claro que a solução é mais limitada que a do Capistrano, mas é uma solução a um problema que possivelmente nunca deveríamos ter, um problema que possivelmente esta mais embaixo, no desenvolvimento.

Pelas estrategias de deploy que o Capistrano tem, os deploy resultam ser um pouco lentos para meu gosto. Eu sei que da para configurar o Capistrano de um jeito e acelerar o processo, mas configurar é uma das coisas que eu não quero fazer. Quero que a ferramenta que utilize trabalhe do melhor jeito possível por padrão. Em todos os casos nos quais trabalhei, o melhor jeito para um deploy mais rápido era o mais simples: git clone no setup e git pull no update, o mesmo que o Inploy faz.

Falando em padrões, com o Capistrano eu achava muito chato por exemplo ter que definir em cada projeto que para dar restart no Passenger o script devia dar um touch no arquivo tmp/restart.txt, ou que em cada deploy ele devia apagar a pasta public/cache e executar a tarefa asset:packager:build_all.

O Inploy tenta resolver esses problemas executando as tarefas comuns por padrão. Já me perguntaram: “E que acontece se eu não estiver utilizando o plugin asset_packager? A tarefa de empacotamento vai dar erro”. A resposta a isso é que a intenção do Inploy é ser um pouco inteligente, executando algumas tarefas somente se elas existem. Hoje ele empacota os assets unicamente se o plugin existir. Uma idéia é que também expire o cache do Memcached ou faça um parse dos arquivos .less, unicamente se eles estiverem sendo utilizados, e coisas assim. Vamos ver ate onde essa inteligencia pode chegar sem afetar outras coisas, mas basicamente a filosofia é que você não tenha que se preocupar com essa aquela tecnologia que você esta utilizando na hora de um deploy, que as coisas simplesmente funcionem sem que podamos errar.

Outra vantagem que eu vejo no Inploy sobre o Capistrano para a maioria dos casos é que somente tem um jeito de fazer deploy, que no Inploy é chamado de update. A tarefa consiste em baixar o código, fazer o que tem que fazer e executar as migrações. Não tem sentido para mim fazer um deploy e não executar as migrações pendentes. Nas equipes com as quais trabalhei, todo mundo conseguia fazer deploy e muitas vesses as pessoas executaram cap deploy quando era para executar cap deploy:migrations. Já me disseram que isso se resolve executando cap deploy:migrations sempre, mas nesse caso a brecha para errar continua existindo, eu prefiro que não exista.

Uma das necessidades que eu tinha com uma ferramenta de deploy é que ela pudesse trabalhar tanto remotamente como localmente. Trabalhei num sistema onde entregamos uma aplicação Rails para um cliente de outro país e as pessoas nesse cliente encarregadas de realizar o deploy não conseguiam faze-lo de outro modo que não seja entrando no servidor e executando alguma coisa. Todos eles utilizavam Windows e estavam acostumados a trabalhar com aplicações Java, onde tinham que entrar no servidor e substituir um arquivo .war e executar uns comandos. A solução nesse caso foi criar um arquivo na pasta raiz do projeto que ao ser executado realizava os passos necessários, aquelas pessoas eram muito limitadas e quando menos pudessem mexer ia ser melhor.

Com o Inploy o problema mencionado anteriormente não existe, devido a que ele pode ser rodado remotamente ou localmente. Ao ser rodado remotamente o único que ele faz é se conetar aos servidores e rodar as tasks como se estive alguem logado. É por tal motivo que atualmente o Inploy é um plugin, de modo que ele se encontre disponível em todos os ambientes.

Hoje, o Inploy somente vai servir para você se você estiver trabalhando com Passenger e com Git. Para poder utilizar ele basta instala-lo na tua aplicação Rails como um plugin. Uma alternativa é faze-lo executando:

script/plugin install git://github.com/dcrec1/inploy.git

O comando acima colocara um arquivo que devemos configurar chamado deploy.rb na pasta config. Esse arquivo é lido pelo plugin e deve estar algo assim:

deploy.application = "inploy"
deploy.repository = 'git://github.com/dcrec1/inploy.git'
deploy.user = 'dcrec1'
deploy.hosts = ['hooters', 'geni']
deploy.path = '/var/local/apps'

Após isso já podemos executar as quatro tarefas rake que o plugin tem:

rake inploy:local:setup
rake inploy:local:update
rake inploy:remote:setup
rake inploy:remote:update

Criei um pequeno vídeo demonstrando como utilizar as diferentes tasks do plugin. No vídeo estou dentro do projeto Signal, que já tem o Inploy incluso e removo ele junto com o arquivo de configuração para demostrar como é fácil instalar e configurar ele. Após isso executo um setup remoto e depois um update remoto. Podemos ver no vídeo que os comandos que o Inploy executa são logados, junto com os outputs correspondentes e que no setup os arquivos config/*.sample são renomeados para config/*. Na segunda parte do vídeo é executado um update local e depois é apagado o repositório, clonado novamente e executado um setup local, outra alternativa do plugin.

Rails deployment made easy with Inploy from Diego Carrion on Vimeo.

Para mais detalhes sobre o plugin podem acessar o repositorio, onde vou tentar manter tudo atualizado no README. Espero que tenha sido claro respeito a como trabalha o Inploy, mas outra opção é dar uma revisada um código, que é bem pequeno (+/- 50 linas de código) e que acredito esta bem claro. Segue um pequeno trecho:

def local_setup
  copy_sample_files
  install_gems
  run "mkdir -p tmp/pids"
  run "./init.sh" if File.exists?("init.sh")
  migrate_database
end

def local_update
  run "git pull origin master"
  install_gems
  migrate_database
  run "rm -R -f public/cache"
  rake_if_included "asset:packager:build_all"
  run "touch tmp/restart.txt"
end

Espero que esse código simples motive as pessoas a colaborar com o projeto e deixar ele cada vez mais espertinho. Qualquer duvida estou sempre a disposição.

E como sempre, considera me apoiar me recomendando no Working With Rails. Para ficar mais perto das novidades, não deixa de me seguir no Twitter.

Tags: Capistrano · deploy · Inploy · rails

8 respostas ate agora ↓

  • 1 Rodrigo Alves Vieira // out 10, 2009 at 11:31 pm

    Parabéns Diego.. é muito bom ver brasileiros contribuindo tanto com iniciativas tão legais!

  • 2 Daniel Lopes // out 11, 2009 at 12:22 pm

    Muito legal cara, parabéns. Eu gosto bastante do Capistrano não apenas pelo deploy mas exatamente por ser bom para criar tarefas de administração, coisas como log tails, log clean, backup e restore do banco, upload dos certificados SSL, esse tipo de coisa.

    Mas sem dúvida o seu projeto é muito bacana, principalmente para projetos menores. Abraços e parabéns novamente.

  • 3 edipofederle // out 13, 2009 at 7:35 pm

    Ola cara, Muito legal o pulugin, fui testar aqui, nam inha hospedagem na locaweb, e quando executo o primeiro comando ali, ele retorna isso:

    rake inploy:remote:setup
    (in /Users/edipofederle/Rails_Projects/edipo_rails)
    Inploy => ssh bitside1@bitside.siteoficial.ws ‘cd /home/bitside1/rails_app/ && git clone git://github.com/edipofederle/edipo_rails.git edipo_rails && cd edipo_rails && rake inploy:local:setup’
    Initialized empty Git repository in /home/bitside1/rails_app/edipo_rails/.git/
    rake aborted!
    Don’t know how to build task ‘inploy:local:setup’

    (See full trace by running task with –trace)

    O que pode ser será?

    T+ valeu

  • 4 Diego Carrion // out 14, 2009 at 9:12 am

    Oi, obrigado por experimentar o plugin.

    O problema é que no servidor não foi baixado o plugin, deve ser porque ele não foi pushado. Da um push no commit com a adição do plugin que tudo deve funcionar.

    Qualquer duvida por favor me avisar.

  • 5 Rodrigo Lazoti // out 14, 2009 at 4:10 pm

    Opa Diego, tudo bem?

    Eu não conhecia esse plugin e seu post me ajudou bastante a entendê-lo de uma forma prática.
    O vídeo ficou show!

    Parabéns pelo post.

  • 6 Diego Carrion // out 16, 2009 at 1:25 am

    @daniel

    Pelas tarefas suponho que você esteja utilizando o script de deploy da Locaweb, ou pelo menos algum similar. Acho que tarefas desse tipo poderiam ir no plugin também, ja que podem funcionar por convensão, como por exemplo dar um tail no log.

    Vou tentar implementar essas coisas, obrigado pelas dicas.

  • 7 Leandro Silva // out 20, 2009 at 8:27 am

    Ótima iniciativa, Diego!

    Pra mim, deploy sempre é uma coisa chata, seja em Java ou em Rails. Já vi equipes que possuem extensos checklists de deployment que sempre tem aquela brecha pra dar merda (ops!) errado.

    Como sempre, parabéns!

  • 8 Resumo das novas funcionalidades no Inploy // dez 18, 2009 at 6:16 pm

    […] ter anunciado o Inploy faz aproximadamente 2 meses, varias pessoas tem colaborado com ele e feito que ganhe mais […]

Deixar um comentário