Dockerizando uma app Rails para desenvolvimento - Parte 1

Tutoriais - 02/Abr/2020 - por Henrique Morato

Neste tutorial vamos ver como trabalhar com contêineres durante o desenvolvimento de uma aplicação Rails. Assim, facilitamos o uso de dependências e não temos a necessidade de instalar nada além de Docker nas nossas máquinas, o que permite a troca rápida de máquinas quando necessário.

Com Docker instalado na máquina (você pode ver como fazer a instalação aqui) vamos começar criando um arquivo invocando a instalação das dependências de um projeto Rails 6 chamado Dockerfile.

Criando o Projeto

Nessa primeira parte vamos criar um projeto Rails do zero dentro do contêiner. Se você já tem um projeto Rails, pode pular essa parte, indo diretamente para o tópico Dockerizando o projeto, mas é interessante começar a partir da criação do projeto porque isso realmente evita que as dependências sejam instaladas na sua máquina. Caso contrário, durante a criação do seu projeto, todas as dependências já foram instaladas antes da "dockerização".

Vamos iniciar criando um arquivo Dockerfile. A primeira linha indica que começaremos de uma imagem da versão desejada de Ruby, no exemplo usaremos 2.7.0.

FROM ruby:2.7.0

Como vamos usar Rails 6, é importante instalar algumas dependências como nodejs e yarn. Depois vamos criar uma pasta para trabalhar facilmente dentro do contêiner.

É interessante criar algumas variáveis de ambientes, opções a serem facilmente customizadas, como: versão do Node e diretório de trabalho no contêiner.

Nosso Dockerfile fica da seguinte forma:

FROM ruby:2.7.0

ENV NODE_VERSION 12
ENV INSTALL_PATH /opt/app

RUN curl -sL https://deb.nodesource.com/setup_$NODE_VERSION.x | bash -

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update -qq
RUN apt-get install -y --no-install-recommends nodejs postgresql-client \
      locales yarn

RUN mkdir -p $INSTALL_PATH

WORKDIR $INSTALL_PATH

Um contêiner é criado a partir de uma imagem que, no nosso caso, vamos fazer com base no arquivo Docker. Usamos o . para referenciar o Dockerfile na pasta em que estamos e a opção --tag para dar um nome para a imagem.

Substitua meu_projeto_rails pelo nome do seu projeto.

$ docker image build --tag meu_projeto_rails .

Em seguida, podemos iniciar um contêiner usando essa imagem. As opções --interactive e --tty permitem a interação com um terminal dentro do contêiner. Também vamos criar um volume para criar uma ponte de mão dupla entre a pasta do nosso projeto e o contêiner.

docker run -it -v "$PWD":/opt/app meu_projeto_rails bash

Então vamos iniciar um projeto Rails usando banco de dados Postgres como exemplo.

$ gem install rails

Em seguida:

$ rails new meu_projeto_rails --database=postgresql

Dockerizando o Projeto

Pronto! Agora que temos um projeto Rails funcional feito no nosso contêiner, podemos sair do contêiner com o comando exit. Lembre-se de copiar o Dockerfile para o nosso projeto Rails.

Dentro da pasta do projeto vamos incrementar nosso Dockerfile com mais opções, como rodar bundle install

FROM ruby:2.7.0

ENV NODE_VERSION 12
ENV INSTALL_PATH /opt/app

RUN curl -sL https://deb.nodesource.com/setup_$NODE_VERSION.x | bash -

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update -qq
RUN apt-get install -y --no-install-recommends nodejs postgresql-client \
      locales yarn

RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
RUN locale-gen
RUN export LC_ALL="en_US.utf8"

RUN mkdir -p $INSTALL_PATH

WORKDIR $INSTALL_PATH
COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock
RUN gem install bundler
RUN bundle install

COPY . $INSTALL_PATH

Sempre que precisar atualizar a imagem com novas gems, basta atualizar a imagem com o comando docker image build -t meu_projeto_rails .. Para desenvolver, é só rodar o comando bash no contêiner, assim você pode utilizar todos os comandos que precisar para desenvolver sua aplicação.

Uma boa dica é lembrar que o contêiner não é a sua máquina, então não use git nele e se precisar rodar o rails server use a opção --binding para permitir outros IPs.

$ rails s -b 0.0.0.0

Vale lembrar que nosso banco de dados ainda não está funcionando porque ele não está instalado na máquina. Você pode modificar o Dockerfile para fazer essa instalação ou usar um banco como SQLite.

Na parte 2 desse tutorial vamos falar sobre como usar o docker-compose para facilitar ainda mais a criação de contêineres!

Até lá!

Foto de perfil do autor
Henrique Morato

Dev e instrutor na Campus Code