Campus Code | Conteúdos | Dockerizando uma App Rails para Desenvolvimento - Parte 2
Dockerizando uma App Rails para Desenvolvimento - Parte 2
Tutoriais - 09/Abr/2020 - por Henrique Morato
Na primeira parte nós montamos um Dockerfile com as dependências do nosso projeto para criar uma imagem que nos forneça o suficiente para rodar essa aplicação Rails.
ENV NODE_VERSION 12
ENV INSTALL_PATH /opt/app
RUN curl -sL https://deb.nodesource.com/setup_$NODE_VERSION.x | bash -
RUN apt-get install -y --no-install-recommends nodejs postgresql-client \
locales yarn
RUN export LC_ALL="en_US.utf8"
COPY . $INSTALL_PATH
Com essa imagem montada, podemos começar a pensar na estrutura do projeto. Até aqui o nosso banco de dados não está funcionando simplesmente porque não está instalado nesse contêiner. Levando em consideração a estrutura de aplicações Web modernas, é bastante comum que aplicação e banco de dados sejam hospedados em máquinas diferentes.
Então vamos montar uma estrutura parecida por meio de contêineres. Isso também dá a liberdade de estender essa estrutura para facilmente colocar um Redis ou outras opções de ferramentas no seu projeto. Pensando nisso, o pessoal da Docker criou o docker-compose, que facilita a integração de contêineres. Onde antes iríamos subir dois contêineres, criar uma conexão entre os dois, exportar portas, etc. agora é uma questão de criar um único arquivo de configuração.
No diretório raiz do nosso projeto, vamos criar o arquivo docker-compose.yml, que faz a ponte entre o banco de dados e a aplicação pra gente.
Se você usa Mac ou Windows, a instalação do Docker Desktop já vem com o compose. Em sistemas Linux ele é instalado separadamente, você pode ler mais aqui.
container_name: meu_projeto_rails
Com esse arquivo criado, podemos executar o comando docker-compose run --service-ports rails bash para subir um contêiner com o nosso projeto. Se você já teve que passar pelo processo de subir duas máquinas e conectá-las, percebeu como o docker-compose tornou tudo muito mais fácil.
O arquivo de configuração define o local onde o contêiner irá buscar a imagem para ser construída (build), nesse caso é a pasta corrente definida pelo .. O Docker busca o arquivo Dockerfile na mesma pasta em que se encontra o docker-compose. A opção --service-ports garante a comunicação da porta 3000 da nossa máquina com a porta 3000 do contêiner. Além disso, como o volume já foi definido nesse arquivo não precisamos mais nos preocupar com isso. Então basta rodar o serviço com o nome que declaramos (no caso, rails) executando o bash.
Feito isso e garantindo que tudo está funcionando, podemos sair do nosso contêiner com o comando exit e começar a configurar o banco de dados.
No docker-compose.yml nós podemos declarar um segundo serviço que será responsável pelo banco de dados. Neste caso chamamos de db.
- meu_projeto_rails_data:/var/lib/postgresql/data
meu_projeto_rails_data:
Declaramos o serviço de banco de dados (db) com algumas variáveis de ambiente importantes (você pode ler mais sobre outras opções para fazer isto aqui). Além disso, fizemos um link, de forma que ao criarmos um contêiner com o serviço rails, um contêiner com o serviço db deve ser criado automaticamente. Configuramos também as mesmas variáveis nesse serviço com um adicional, que é o nome do serviço que está hospedando o banco de dados, nesse caso, db.
Caso você faça modificações no Dockerfile é importante atualizar o cache com um docker-compose build.
Quando executarmos docker-compose run --service-ports rails bash, o script irá reconhecer que deve subir um segundo contêiner com um banco de dados usando a imagem do postgres disponível no Docker Hub.
Mas para fazer tudo funcionar temos que usar o arquivo config/database.yml da nossa aplicação Rails para usar as variáveis de ambiente que declaramos com a senha e host do banco.
O arquivo tem muitas linhas, mas parte importante é troca do default incluindo o usuário, senha e host do banco.
username: <%= ENV.fetch("POSTGRES_USER") %>
password: <%= ENV.fetch("POSTGRES_PASSWORD") %>
host: <%= ENV.fetch("POSTGRES_HOST") %>
Assim, temos o nosso banco funcionando num outro contêiner e de forma extensível para inclusão de um Redis, camada de cache, entre outras coisas necessárias ao nosso ambiente de desenvolvimento.
Projeto rodando com docker-compose run --service-ports rails bash, fazer um bin/setup, e rails server --binding 0.0.0.0, bora codar!?