Desenvolver em Rails, utilizando o Docker fora do Linux com Vagrant

Um dia desses vi no twitter um desenvolvedor conceituado na área falando: “Esse docker está dominando o mercado”. É clara a importância que muitos devs estão dando a ferramenta mesmo ela não estando ainda em produção segundo os próprios criadores.

O docker é desenvolvido sobre o LXC, sendo exclusivo aos SO’s Linux, o desenvolvimento em qualquer outra plataforma acaba sendo não tão transparente. O site do docker  traz alternativa para desenvolver em outras plataformas como MacOs X e Windows, o Boot2docker .

O boot2docker é uma distribuição linux feita para rodar containers Docker. É a ferramenta padrão e roda em cima do VirtualBox .

Mesmo sendo a ferramenta padrão ela não trouxe à equipe uma produtividade esperada. ISO padrão não suportando Guest Additions  e compartilhamento de pastas dentro da VM faz com que o Rails fique lento, por exemplo, uma requisição durar 30 ~ 40 segundos, tornando o desenvolvimento inviável. Além do fato que queríamos a maior fidelidade possível do ambiente de produção, no caso, temos um Linux versão 14.04 no ar, com boot2docker não temos esse controle da versão do SO.

#Atualizar ISO para suportar Guest Additions
$ curl http://static.dockerfiles.io/boot2docker-v1.2.0-virtualbox-guest-additions-v4.3.14.iso > ~/.boot2docker/boot2docker.iso

#Compartilhamento do projeto e montagem do diretório dentro da VM.
$ cd ~/workspace
$ VBoxManage sharedfolder add boot2docker-vm -name apps -hostpath $PWD

$ boot2docker ssh “sudo modprobe vboxsf && sudo mkdir -v -p /apps && sudo mount -v -t vboxsf -o uid=0,gid=0 apps /apps”

O Vagrant nos trouxe melhoria em todos esses pontos, tornando workflow de desenvolvimento bem mais simples. Mas o que seria o Vagrant? Trata-se de um software para criação e configuração de ambientes virtuais de desenvolvimento. É uma ferramenta gratuita e open-source escrita em Ruby, funcionando como um Wrapper sobre VMs como VirtualBox e VMWare.

Criando um Ambiente utilizando o Vagrant

Primeiramente, o Vagrant suporta alguns provedores de máquinas virtuais. Nesse post usaremos o VirtualBox, então é necessária a instalação prévia. Após a instalação do VirtualBox, a instalação do Vagrant torna-se simples, sendo apenas um instalador disponível para MacOS X e Windows.

Passos para criação de um ambiente Vagrant.

1) Criamos um novo projeto Rails ou fazemos um clone de algum repositório Rails no github.

2) A documentação do Vagrant é extensa, com uma séries de comandos disponíveis para linha de comando, mas também é possível criar o ambiente a partir do arquivo “Vagrantfile”. É um arquivo com sintaxe ruby que apresenta todos os passos para criação da VM.

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.network "private_network", ip: "192.168.50.4"
  config.vm.network "forwarded_port", guest: 4243, host: 4243
  $script = <<SCRIPT
wget -q -O - https://get.docker.io/gpg | apt-key add -
echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list
apt-get update -qq
apt-get install -q -y --force-yes lxc-docker
usermod -a -G docker vagrant
sed -e 's/DOCKER_OPTS=/DOCKER_OPTS=\"-H 0.0.0.0:4243\"/g' /etc/init/docker.conf > /vagrant/docker.conf.sed
cp /vagrant/docker.conf.sed /etc/init/docker.conf
rm -f /vagrant/docker.conf.sed
service docker restart
SCRIPT
  config.vm.provision :shell, :inline => $script
  config.vm.synced_folder ".", "/vagrant", type: "nfs"

  config.vm.provider :virtualbox do |virtualbox|
    virtualbox.customize ["modifyvm", :id, "--memory", "2048"]
    virtualbox.customize ["modifyvm", :id, "--cpuexecutioncap", "50"]
  end
end

Adicionamos esse arquivo na raiz do nosso projeto Rails, pois vamos utilizar alguns padrões que o Vagrant utiliza para facilitar nossa vida, além de ter a documentação de criação do seu ambiente dentro do diretório do projeto.

Entendendo um pouco cada passo do Vagrantfile, temos:

config.vm.box = "ubuntu/trusty64"

No Vagrantcloud  temos uma lista de várias imagens disponíveis para usarmos como ambiente, no caso usaremos o linux 14.04, semelhante ao nosso ambiente de produção.

config.vm.network "private_network", ip: "192.168.50.4"

Fixamos o endereço de IP pois será necessário nos próximos passos da configuração

config.vm.provision :shell, :inline => $script

Executamos o Script de instalação do docker.

config.vm.synced_folder ".", "/vagrant", type: "nfs"

Por padrão o vagrant compartilha a pasta do projeto para dentro de /vagrant, montamos para poder alterar o código e refletir dentro na VM. Compartilhando como NFS, a lentidão que tínhamos no boot2docker desaparece, além da sintaxe ser bem mais simples.

3) executamos:

$ cd vagrant up

Caso for a primeira vez que executamos o comando, o vagrant interpretará o vagrantfile e realizará o download da imagem do vagrantcloud e executará os scripts de instalação do vagrant.

4) Caso o ambiente for MacOS X, podemos acessar a VM com o comando:

$ cd vagrant ssh

Se no caso, for Windows, não temos essa facilidade. Precisamos de um cliente para nos comunicarmos ssh com a VM. Utilizaremos o putty http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html.
Para mais detalhes da configuração da ferramenta, acesse o post do SimplesIdeias,  lá traz um tutorial bem mais completo de configuração do Vagrant no Windows.

vagrant1

5) Acessando o vagrant, já podemos utilizar o docker. Primeiramente adicionamos o DOCKER_HOST com o IP que configuramos no vagrantfile e porta do docker também configurada no script:

$ export DOCKER_HOST=tcp://192.168.50.4:4243

A partir de então estamos aptos ao docker.

Para desenvolver com rails precisamos de um linux com ruby instalado e um banco de dados. Então usaremos containers disponíveis no docker hub com ambientes prontos. Utilizaremos a imagem oficial do postgres e a imagem da fortes com linux e ruby.

$ docker run —-name postgres -rm -d postgres

$ docker run -ti -v /vagrant/:/home/app -p 3000:3000 —-link postgres:postgres fortes/ruby:latest /bin/bash -l

Mais detalhes podem ser visto na documentação do docker, mas explicando o que foi feito:

–name criamos um nome que será usado para criar um link entre os containers
-d o container é executado em background
-ti o container é executado em modo interativo, no caso executando o comando que é o ultimo parâmetro. No exemplo, iniciamos o container no bash “/bin/bash -l”
-v compartilhamos o diretório do projeto que está dentro de /vagrant (lembra?) para dentro do container. No exemplo, dentro do diretório /home/app
-p 3000:3000 abrimos a porta 3000 que será usada pelo rails, mapeando a porta 3000 do vagrant com a respectiva porta equivalente dentro do container, no caso também a 3000.
–link criamos o link entre os containers do BD e da app.

Dentro do container vamos ao teste final, criando o banco de dados, gerando um scaffold de User(name, email), executamos a migrate e iniciamos o rails server.

$ rake db:create
$ rails g scaffold User name:string email:string
$ rake db:migrate
$ rails s

vagrant2

Opa, vemos um erro. O rails não achou o servidor de banco de dados. Vemos a mágica no arquivo database.yml:

development:
adapter: postgresql
encoding: utf8
database: bookmaker_development
host: localhost
pool: 5
username: postgres
password: postgres
port: 5432

Substituímos o host “localhost” para a url do postgres, no qual criamos o link para comunicação com nosso container que irá rodar nossa app.

host: postgres

Novamente:
$ rails s

No browser, acesse o IP da sua VM com a porta 3000 para visualizar a app no ar.

vagrant3

Anúncios

2 comentários sobre “Desenvolver em Rails, utilizando o Docker fora do Linux com Vagrant

  1. Boa noite.
    Estou começando com o Docker hoje no Windows. Realmente eu preciso do Vagrant + Docker?
    Seria possível utilizar um container do Ubuntu + um container do Rails e trabalhar junto?

    Desde já agradeço.

  2. Bom dia Renato, tanto no windows quanto no macosX você precisa de uma VM com linux. Lembra que o docker é baseado no conceito de LXC, e esse conceito só está presente no linux. Há alternativas ao vagrant como o boot2docker. Faz tempo que não uso, na época o vagrant foi uma alternativa melhor para mim, bem mais flexível e fácil configuração.

    abraço

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s