DevOps, Ruby On Rails

Ruby 2.0.0-p247 no Ubuntu 12.04 LTS via apt-get

Este post poderia se chamar também “Como criar pacotes Debian do Ruby 2.0.0 ou de qualquer outra versão“, já que é exatamente isso que vou ensinar.

Não se preocupe, por que não existe nenhum trabalho manual ou muito complicado, pra falar a verdade é muito mais simples do que você imagina, e com isso, você ganha uma instalação muito mais rápida no servidor de produção, seja pra uma máquina ou pra 10mil.

Se você está lendo este artigo, espero que já esteja convencido sobre por que utilizar RVM ou Rbenv em produção é uma má idéia, mas se você ainda tem dúvida, alguns argumentos para auxiliar na sua decisão:

  1. Se você não utiliza o sistema de pacotes do seu sistema operacional, você perde toda a gerência de dependências que vem com ele, e com isso, corre o risco de alguém inadvertidamente quebrar a sua instalação customizada e compilada, instalando um pacote mais antigo do que o instalado manualmente.
  2. Utilizando pacotes você consegue gerenciar facilmente atualizações, bem como garantir que todas as dependências também estão atualizadas.
  3. Compilar Ruby em produção vai degradar a performance da máquina, durante todo o processo de compilação, sem contar que será necessário instalar uma quantidade grande de dependências que não seriam normalmente utilizadas se você já tivesse o pacote compilado.
  4. Difícil automatizar, já que você não tem muito controle sobre o que pode acontecer durante um processo de compilação. Uma compilação pode falhar em uma das máquinas e você dificilmente vai ficar sabendo disso, se esse procedimento for ser executado em muitas máquinas ao mesmo tempo e de forma regular.
  5. Desperdício de recurso ter compilar a mesma coisa em várias máquinas.

Se você ainda achar que os argumentos acima não são suficientes, talvez a facilidade de se gerar o pacote possa te convencer o contrário.

Vamos por mãos na massa. Para gerar nosso pacote com a versão atualizada do Ruby, você vai precisar ter as seguintes ferramentas instaladas:

  • Vagrant (Gerenciador de virtualização, trabalha com Virtualbox, VMWare, LXC, e serviços de cloud como AWS, DigitalOcean)
  • Ruby 1.9.3 ou superior
  • Bundler
  • Chef (você pode instalar pelo link ao lado, ou via gem install chef)
  • Git

A solução que encontrei recentemente, se baseia na compilação utilizando o Vagrant, que gerencia o fluxo de vida de uma máquina virtual, inclusive a instalação de pacotes e configuração automatizada da mesma. É uma ferramenta que tem diversas funcionalidades para auxiliar no desenvolvimento de aplicações que dependem de arquitetura distribuída, e que vai servir como uma luva para nossa necessidade.

A primeira coisa é instalar alguns plugins do Vagrant que vão auxiliar o restante do processo:

vagrant plugin install vagrant-berkshelf
vagrant plugin install vagrant-omnibus

# se não quiser gerar para ambas arquitetura, adicione somente a que quiser
vagrant box add "ubuntu-12.04-64" "http://files.vagrantup.com/precise64.box"
vagrant box add "ubuntu-12.04-32" "http://files.vagrantup.com/precise32.box"

Vamos baixar o repositório do projeto chef-ruby_pkg e terminar de instalar as dependências que ele solicita:

git clone https://github.com/reaktor/chef-ruby_pkg.git
cd ruby_pkg
bundle install --without development:test

Pronto, agora é só escolher qual arquitetura que você quer utilizar (32bits ou 64bits) e mandar gerar o pacote:

# Para gerar os pacotes 32bits:
VERSION="2.0.0-p247" BOX="ubuntu-12.04-32" vagrant up
VERSION="2.0.0-p247" BOX="ubuntu-12.04-32" vagrant provision

# para gerar os pacotes 64bits: 
VERSION="2.0.0-p247" BOX="ubuntu-12.04-64" vagrant up
VERSION="2.0.0-p247" BOX="ubuntu-12.04-64" vagrant provision

Se tudo correr bem, você terá o pacote pronto na pasta”pkg” dentro do próprio projeto. No meu caso, eu precisava compilar para 32bits, e o resultado foi esse arquivo aqui: “ubuntu-12.04_ruby-2.0.0-p247-1_i386.deb”, com isso feito, é só subir na máquina e mandar instalar via dpkg -i ubuntu-12.04_ruby-2.0.0-p247-1_i386.deb

Caso queira compilar para ambas arquiteturas, é necessário desligar a máquina virtual e carregá-la novamente com o comando acima.

Para desligar a máquina é só digitar vagrant halt.

Padrão