Olá você que está lendo este post por algum motivo!
Não sei como iniciar um diário de desenvolvimento corretamente, creio que seja a primeira vez que faço algo assim e também é a primeira vez que escrevo um artigo completo aqui no site. Portanto, peço desculpas se o formato ficar estranho.
Mas acho que você está aqui porque talvez queira criar um pequeno projeto em Rails e aprender um pouco mais sobre Docker. E é exatamente isso que eu também quero! Portanto, esta entrada no diário é minha tentativa de construir uma base para projetos e um passo a passo para você construir também.
Então vamos lá!
Sobre o projeto
Estou em período de mudança e ainda não comprei uma estante para guardar meus livros, que estão todos jogados pelo chão do escritório. Como está tudo bagunçado não sei quantos livros são, quais são, se perdi algum na mudança, e não consigo definir uma lista do que irei ler.
Então a ideia é simples (na verdade extremamente complicada pois poderia usar uma planilha), construir uma API que converse com um banco de dados e guarde informações dos livros que tenho.
Instalando Ruby e Rails na sua máquina
A primeira coisa é baixar e instalar o Ruby, você pode usar a instalação padrão ou algum gerenciador de versões. No meu caso estou usando rbenv, e se você estiver usando linux recomendo também, é simples e gosto bastante.
Para este projeto estou usando ruby 3.2.0, mas fique à vontade para usar a versão mais estável/recente disponível.
Depois de instalar o Ruby, instalei a gem de Rails e mais algumas relacionadas ao rubocop para lint direto no meu editor de código (eu estou usando vscode com as extensões ruby e ruby-rubocop).
gem install rails
gem install rubocop
gem install rubocop-rails
gem install rubocop-performance
Criando uma API Rails com Postgres
Onde trabalho e em vários outros projetos geralmente utilizo PostgreSQL, estou acostumado com o comportamento e a interface de gerenciamento, configurei ele para ser o banco de dados principal. E como esse projeto será uma API, configurei a flag do Rails para não criar arquivos front-end (criarei um projeto separado para consumir a API mais tarde, provavelmente em VueJS).
Fui em um gerador de nomes que me retornou algumas opções de nome do projeto, coloquei o nome como booksica.
rails new booksica-api --api --database=postgresql
Também criei o arquivo de licença como MIT para especificar o direito de qualquer pessoa de baixar, usar e modificar o projeto.
Usando Docker para executar o projeto
Apesar de estar acostumado com o Postgres, não quero instalá-lo na minha máquina, nem usar o Rails diretamente. E por motivos de compatibilidade com outros computadores (e até para você mesmo baixar e executar esse projeto) resolvi usar containers Docker. Se quiser, basta seguir este passo a passo da instalação.
Criei meu Dockerfile com as configurações necessárias para um projeto Rails, e um entrypoint.sh, que exclui o arquivo server.pid pois às vezes ele não é removido caso o container não seja desligado corretamente (gerando um erro ao executá-lo novamente).
Outro ponto a ser mencionado é a configuração BUNDLE_FROZEN, que sempre força uma comparação entre o Gemfile e o Gemfile.lock, e se as versões forem diferentes o projeto não inicia (mais uma configuração de segurança).
Dockerfile
# syntax = docker/dockerfile:1
# Versão do ruby que será usada
FROM ruby:3.2.0
# Instalação de dependências
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y postgresql-client
# Configuração do BUNDLE_FROZEN
RUN bundle config --global frozen 1
# Criação do diretório de trabalho
WORKDIR /booksica-api
# Cópia dos arquivos e instalação das gems
COPY Gemfile Gemfile.lock ./
RUN bundle install
# Rodar o arquivo de entrypoint para deletar o server.pid
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
# Escutar porta 3000 e rodar o servidor
EXPOSE 3000
CMD ["./bin/rails", "server", "-b", "0.0.0.0"]
entrypoint.sh
#!/bin/bash
set -e
rm -f /booksica-api/tmp/pids/server.pid
exec "$@"
Configurando variáveis do banco de dados
Antes de rodar o projeto, corrigi algumas configurações para que o ele pudesse se conectar ao banco de dados. Coloquei host, username e password como variáveis de ambiente, que serão passadas tanto pelo arquivo de configuração do container, quanto em um arquivo .env caso precise ser executado localmente em algum momento. As variáveis estão no escopo default, portanto, o banco de dados de desenvolvimento e de teste tem as mesmas credenciais.
config/database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: <%= ENV['DBHOST'] %>
username: <%= ENV['DBUSER'] %>
password: <%= ENV['DBPASS'] %>
development:
<<: *default
database: booksica_api_development
test:
<<: *default
database: booksica_api_test
production:
<<: *default
database: booksica_api_production
username: booksica_api
password: <%= ENV["BOOKSICA_API_DATABASE_PASSWORD"] %>
.env
DBHOST=localhost
DBUSER=postgres
DBPASS=password
Criando um arquivo docker compose
Por fim, para poder executar o projeto, criei um arquivo docker-compose.yml contendo os seguintes serviços:
- Um serviço de banco de dados utilizando a imagem do Postgres;
- Um serviço administrador de banco de dados com a imagem pgAdmin (opcional);
- Um serviço rails executando meu projeto pelo Dockerfile;
docker-compose.yml
version: '3.8'
services:
booksica-db:
image: postgres
container_name: booksica-db
volumes:
- postgres:/var/lib/postgresql/data
environment:
POSTGRES_DB: "booksica_api_development"
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "password"
ports:
- "5432:5432"
networks:
- booksica-api-network
booksica-pgadmin:
image: dpage/pgadmin4
container_name: booksica-pgadmin
environment:
PGADMIN_DEFAULT_EMAIL: "user@booksica.com"
PGADMIN_DEFAULT_PASSWORD: "password"
ports:
- "15432:80"
depends_on:
- booksica-db
networks:
- booksica-api-network
booksica-api:
image: booksica-api
container_name: booksica-api
build: .
environment:
- DBHOST=booksica-db
- DBUSER=postgres
- DBPASS=password
volumes:
- .:/booksica-api
ports:
- "3000:3000"
depends_on:
- booksica-db
networks:
- booksica-api-network
networks:
booksica-api-network:
driver: bridge
volumes:
postgres:
Alguns pontos são interessantes de falar, todos os serviços possuem variáveis de ambiente definidas, as variáveis do booksica-db e booksica-api são de acesso ao banco de dados, e as do booksica-pgadmin credenciais de acesso ao painel do administrador. Os serviços API e pgAdmin dependem do banco de dados, portanto, se você subir qualquer um deles, o serviço de banco de dados será carregado automaticamente.
Outro ponto é que criei uma network separada para os serviços se comunicarem, só acho mais fácil encontrá-la dando um nome específico. Se você quiser saber mais sobre as tags do docker compose eu recomendo a documentação oficial, o Docker é apenas assustador no começo, com o tempo você se acostuma.
Rodando o projeto
Por fim, depois de tantas configurações, montei os containers do projeto e subi os serviços:
docker compose build
docker compose up
Em outro terminal entrei no container principal do projeto (booksica-api) com o comando bash para realizar a migração do banco de dados:
docker compose exec booksica-api bash
rails db:create
rails db:migrate
E logo após reiniciar os serviços tenho a confirmação de que está tudo funcionando.
Também acessei o serviço pgAdmin para testar se o banco de dados foi criado corretamente.
Conclusão
Por hoje é isso! O projeto está funcionando e pronto para as próximas mudanças, depois farei uma nova entrada aqui mostrando o processo de criação de um fluxo de trabalho de CI com Github Actions.
Se você tiver alguma dúvida ou dica sobre como posso melhorar o projeto (ou mesmo este post), fique à vontade para me enviar! Minha ideia é que esse diário de desenvolvimento seja periódico e não leve muito tempo (por mais que eu suma vez ou outra).
Link para o projeto
https://github.com/betosardinha/booksica-api
Música aleatória para você escutar
Top comments (0)