Criando sua Vagrant Box: CentOS 7 + Passenger + NGINX + Múltiplas Versões Ruby (rbenv) e Rails

Para a customização dessa box foram utilizadas as seguintes tecnologias e versões:

  • CentOS 7
  • Vagrant: 1.8.1
  • Virtual Box: 5.0.20 r106931
  • Phusion Passenger: 5.0.28
  • NGINX: 1.10.0
  • Ruby: 2.1.3 e 1.9.3-p550
  • Rails: 4.2.6 e 3.2.22.2

Antes de iniciar o processo será necessário ter instalado o Vagrant e Virtual Box. Também será necessário instalar o plugin vagrant-vbguest

$ vagrant plugin install vagrant-vbguest

vagrant-vbguest

Essa customização será realizada a partir da box centos/7.

$ vagrant init centos/7

Esse comando irá criar o Vagrantfile. Porém será necessário adicionar a configuração config.ssh.insert_key = false. Essa configuração é importante para continuar usando a chave pública padrão do Vagrant.

Segue abaixo Vagrantfile que utilizei para essa customização com mais algumas configurações. Nesse arquivo estou definindo o IP 192.168.50.4, config.vm.network :private_network, ip: "192.168.50.4", e os diretórios que serão sincronizados entre a máquina local e a virtual config.vm.synced_folder "~/workspace", "/var/www", nfs: true. Para esse compartilhamento de diretórios estou utilizando a tecnologia NFS, lembrando que a mesma não funciona no Windows como host.

$ vagrant up --provider virtualbox

Iniciando a máquina, na primeira vez que for executado, será realizado o download da box, e por isso poderá demorar um pouco.

Download Box

O próximo passo é acessar o seu servidor por SSH.

$ vagrant box ssh

vagrant-ssh

Caso tenha problemas nessa etapa, recomendo esse tutorial, escrito pelo @fnando.

Dentro da Box

Geralmente antes de começar a instalar os novos pacotes, vamos atualizar os já existentes.

$ sudo yum update

Ruby

Para trabalhar com diferentes versões de Ruby, vamos utilizar o rbenv

Instalando dependências:

sudo yum install -y git-core zlib zlib-devel gcc-c++ patch readline readline-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison curl sqlite-devel libcurl-devel

Instalando rbenv:

cd ~
git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

Instalando ruby-build:

git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile

Finalmente, instalando o ruby.

Nessa box vamos instalar duas versões do ruby, uma antiga (1.9.3-p550) e a mais atual até o momento que era escrito esse tutorial (2.3.1). Porém, vamos definir o ruby 2.3.1 como a versão global.

Instalando ruby 2.3.1, e definindo como a versão global (Isso pode demorar um pouco).

$ rbenv install 2.3.1
$ rbenv global 2.3.1

Verificar se o ruby foi instalado corretamente.

$ ruby -v

rbenv-ruby2.3.1

Instalando o ruby 1.9.3-p550.

$ rbenv install 1.9.3-p550

Obs.: Esse tutorial está utilizando o ruby 1.9.3 apenas como finalidade de exemplo, lembrando que essa versão está descontinuada, e não deve ser utilizada em ambientes de produção, pois não há mais suporte a mesma.

rbenv-ruby1.9.3

Verificando as versões instaladas.

$ rbenv versions

rbenv-versions

Dica: Caso você não queira realizar o download da documentação de toda gem que instalar, já que esse processo pode ser demorado. Você pode desabilitar isso, através desse comando.

$ echo "gem: --no-document" > ~/.gemrc

Você também vai querer instalar a gem bundler, para gerenciar as dependências de suas aplicações.

$ gem install bundler

Passenger + NGINX

Vamos utilizar a instalação do Passenger através da gem, compilando o NGINX.

$ gem install passenger -v 5.0.28

Será necessário aplicar permissões ao diretório /home/vagrant, e ao diretórios onde suas aplicações vão estar, nesse exemplo em /var/www/.

$ sudo chmod o+x /home/vagrant
$ sudo chmod o+x /var/www

Quando instalamos a gem passenger, também foi instalado o binário passenger-install-nginx-module, o qual iremos utilizar para instalar o NGINX, porém como vamos utilizar o mesmo junto com o rbenv, por isso é necessário que sua execução siga as seguintes etapas:

$ export ORIG_PATH="$PATH"
$ sudo -s -E
$ export PATH="$ORIG_PATH"
$ /home/vagrant/.rbenv/versions/2.3.1/bin/ruby /home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/passenger-5.0.28/bin/passenger-install-nginx-module

passenger-install-nginx-module

Agora é só seguir as instruções conforme sua necessidade.

  • Ruby é a linguagem que desejamos;

passenger-ruby

  • A opção 1, irá realizar o download, compilar e instalar o NGINX para nós;

passenger-nginx

  • Vamos manter o diretório /opt/nginx, como sugerido, portanto basta apertar enter;

passenger-directory

  • E por fim criar o arquivo /opt/nginx/conf/nginx.conf.

passenger-nginx-conf

Agora vamos adicionar o systemd nginx.service ao systemctl do CentOS, para isso deve salvar o arquivo abaixo em /lib/systemd/system/nginx.service.

E depois iniciar e habilitar o serviço:

$ sudo systemctl start nginx.service
$ sudo systemctl enable nginx.service

Você pode verificar a situação do NGINX através do comando:

$ sudo service nginx status

nginx-status

Se ainda estiver como root, podemos voltar a utilizar o usuário vagrant, e recarregar as configurações contidas no .bash_profile.

$ su vagrant
$ source ~/.bash_profile

Aplicações Ruby on Rails

Para exemplificar vamos utilizar duas aplicações, dummy utilizando ruby 2.1.3 e rails 4.2.6, e dummy_old, utilizando ruby 1.9.3-p550 e rails 3.2.22.2.

$ git clone https://github.com/gabrielpedepera/dummy.git /var/www/dummy

$ git clone https://github.com/gabrielpedepera/dummy_old.git /var/www/dummy_old

Para instalar as dependências utilize o comando bundle install em cada aplicação (Lembre-se de instalar o bundler em cada versão do ruby).

$ cd /var/www/dummy
$ gem install bundler
$ bundle install
$ cd /var/www/dummy_old
$ gem install bundler
$ bundle install

Substitua o conteúdo do arquivo /opt/nginx/conf/nginx.conf abaixo (Essa edição deve ser utilizada com o usuário root):

Reinicialize o serviço NGINX.

$ sudo service nginx restart

No começo desse tutorial adicionamos o IP 192.168.50.4 ao Vagrantfile, e nesse momento vamos adicionar a seguinte linha ao arquivo /etc/hosts de sua máquina local.

192.168.50.4 localhost.dummy localhost.dummy_old

Agora é possível acessar as aplicações através do navegador. Veja que é possível verificar as versões de ruby e rails diferentes.

Dummy - http://localhost.dummy: (ruby 2.1.3 + rails 4.2.6):

dummy

Dummy Old - http://localhost.dummy_old: (ruby 1.9.3-p550 + rails 3.2.22.2):

dummy-old

Exportando a nova box

Terminada as customizações, agora vamos limpar os dados do yum, o histórico de comandos e desligar o servidor.

$ sudo yum clean all
$ cat /dev/null > ~/.bash_history && sudo shutdown -h now

Para empacotar a nova VM, deve se utilizar o comando abaixo, o argumento --baserecebe o nome da VM no VirtualBox, e --output o nome do arquivo a ser gerado.

virtual-box

$ vagrant package --base workspace_default_1472086496235_78098 --output vagrant-centos7.box

virtual-box

Se tudo ocorreu bem, você terá uma nova VM provisionada pelo Vagrant, já podendo ser utilizada.

$ vagrant box add vagrant-centos7 vagrant-centos7.box
$ vagrant init vagrant-centos7
$ vagrant up