Ruby on Rails + Docker e docker-compose - Parte 01

Montando o ambiente de desenvolvimento

Montando o ambiente de desenvolvimento ruby on rails com docker e docker-compose

Fala gente! hoje eu mostrar pra vocês como montar um ambiente de desenvolvimento(Ruby on Rails) usando docker e docker-compose.

Para tal eu vou assumir que já tenha o docker e o docker-compose instalados. Link para a instalação do docker no Mac

Antes de começarmos gostaria de dizer que não irei abordar muito a parte sobre como o docker funciona desde o início. Vou tentar abordar o essencial e dá algumas dicas de como ser produtivo e entender o necessário pra poder usar docker e docker-compose no dia-a-dia.

Se você realmente entender como docker trabalha pode replicar este conhecimento pra qualquer tipo de ambiente. Eu particularmente uso tudo em docker. :)

A Receita de Bolo

Eu vou me basear no quickstart da documentação oficial do docker pra inicializar o projeto. Fique tranquilo, apesar de ser um quickstart, se você for usar essa image, pouca coisa irá mudar pra montar um ambiente de produção pra o mundo real. https://docs.docker.com/compose/rails

A primeira coisa que você deve fazer criar um diretório que levará o nome da sua aplicação.

Por exemplo:

mkdir store_api

Dockerfile

Dentro deste diretório crie um arquivo chamado Dockerfle com o seguinte conteúdo;

FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /store_api
WORKDIR /store_api
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /store_api/Gemfile.lock
RUN bundle install
COPY . /store_api

Gemfile

Crie também um arquivo Gemfile, pra que é de Ruby já deve manjar, que inicialmente terá o seguinte conteúdo:

source 'https://rubygems.org'
gem 'rails', '~>5'

E um arquivo um arquivo Gemfile.lock vazio mesmo.

Eu mudei umas coisinhas em relação a doc oficial do docker mas o resultado final é o mesmo.

Docker Compose

Esse cara é o que mais gosto pelo fato de ser muito fácil de usar logo que você entende como a coisa funciona.

version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  app:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

“Buildando” o Projeto

O comando a seguir irá criar o seu projeto.

docker-compose run app rails new . --api --force --no-deps - database=postgresql

⚠️ Aqui vale uma alerta. Se você estiver usando Linux vale lembrar que os arquivos que serão criado pelo rails são criado pelo usuário ROOT do container, logo, você não terá permissão pra alterar os arquivos foram criados, então, basta mudar as permissões do diretório do seu projeto pro seu usuário.

Você pode fazer conforme recomendação da documentação oficial e executar o seguinte:

sudo chown -R $USER:$USER .

Se você tiver rodando no mac isso não vai ser necessário.

Build

Agora que você possui um novo Gemfile, você precisa criar uma imagem novamente. Toda vez que você modificar o seu Gemfile você irá precisar buildar uma nova imagem.

Conectando o banco de dados

Se você executar o comando doker ps ira perceber que há alguns containers na sua máquina.

Agora.... como vamos conectar o container de app ao banco, que está rodando em um container separado?

Muito simples! Vamos modificar o arquivo database.yml pra dizer a aplicação as informações de onde ela irá tentar se conectar ao banco de dados.

O seu arquivo config/database.yml deve se parecer com este:

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: 5

development:
  <<: *default
  database: store_api_development


test:
  <<: *default
  database: store_api_test

Esse db vem de onde?

Como especificado lá docker-compose.yml a palavra chave chamada db, é uma espécie de DNS do container que identifica o serviço dentro da rede do docker.

Lembrando que todo container tem um IPinterno e esses IPs mudam o tempo todo conforme você cria/apapga um container. Pra não haver problemas a declaração da chave vai identificar o container. Também é possível fixar um IP mas pra este propósito não será necessário. Apenas entenda que agora toda vez que você quiser se referir ao banco de dado basta usar a palavra chave db.

RAKE DB

Agora vamos criar o bando de dados e ver e se tudo funcionou.

Vamos executar o comando que do docker-compose que irá ler o arquivo que criamos e subir as imagens lá definidas.

docker-compose up

Se tudo tiver dado certo você irá uns logs mais ou menos assim no seu terminal:

rails_db_1 is up-to-date
Creating rails_app_1 ... done
Attaching to rails_db_1, rails_app_1
db_1   | PostgreSQL init process complete; ready for start up.
db_1   |
db_1   | 2018-03-21 20:18:37.437 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db_1   | 2018-03-21 20:18:37.437 UTC [1] LOG:  listening on IPv6 address "::", port 5432
db_1   | 2018-03-21 20:18:37.443 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1   | 2018-03-21 20:18:37.726 UTC [55] LOG:  database system was shut down at 2018-03-21 20:18:37 UTC
db_1   | 2018-03-21 20:18:37.772 UTC [1] LOG:  database system is ready to accept connections

Se tudo ocorreu bem agora você só precisa rodar o comando que irá criar o banco de dados:

docker-compose run app rake db:create

Então: 1 - Docker-compose run: É pra rodar um comando dentro de um container. 2 - app o argumento que vem logo em seguida é o nome do container onde você vai querer executar os comandos (de novo a chave que indicamos no docker-compose) 3 - rake db:create aí se você é rubysta dispensa apresentações. 😎

Starting rails_db_1 ... done
Created database 'store_api_development'
Created database 'store_api_test'

Hello

Ufa! A principio parece que é muita coisa mas como eu descrevi lá em cima… é tudo uma receita de bolo.

Abra seu browser e acesse http://localhost:3000 ruby on rails home page

Viva! Tudo funcionando!

Na próxima parte eu vou mostrar mais coisas relacionadas ao workflow de trabalho usando ambiente que montamos por aqui.

Até a próxima e vlw!

Comentários