Configurando-Docker-para-Ruby-3.4.5+Rails-8

Documentação Configurando Docker para Ruby 3.4.5 + Rails 8

  1. Inicie um novo projeto com Tailwind baseado nesta documentação: - Ruby + Flowbite + Tailwind

  2. Esta documentação é uma base para nosso projeto: - Projeto Truck manager

  • Esta documentação serve como base para configurar um ambiente de desenvolvimento com Docker utilizando Ruby 3.4.5, Rails 8, PostgreSQL, Redis, Sidekiq e ferramentas de teste como RSpec.

  • O objetivo é preparar uma stack completa para desenvolvimento, testes e execução de workers, com exemplos de configuração de variáveis de ambiente, containers Docker, scripts de setup e dependências de sistema.

  1. Visão Geral da Stack:

- Componentes principais utilizados neste setup:

- Ruby 3.4.5

- Rails 8

- Postgresql 15.7

- redis 7.0

- Sidekiq 7.0

- RSpec 7.0

- Node.js 20.x

- Yarn 1.22.1

1. Instalação de Gems Necessárias

Antes de mais nada, adicione ao seu Gemfile as gems essenciais: Sidekiq, RSpec, pg (adaptador PostgreSQL). Isto ajudará tanto no desenvolvimento quanto na manutenção do código.

  • Adiciona a gem RSpec dentro de um grupo de development e test:

group :development, :test do
  # Use RSpec for testing [https://rspec.info/]
  gem "rspec-rails", "~> 7.0"
end
  • Adiciona a gem sidekiq:

gem "sidekiq", "~> 7.0"
  • Adiciona a Gem pg:

gem "pg", "~> 1.1"

2. Dockerfile para web db e testes

Este arquivo define a imagem base, instala dependências do sistema, configura timezone, cópia de código, instalação de gems, Node + Yarn, e define o comando padrão do container web. É o coração da construção da imagem Docker da sua aplicação.

Algumas coisas a destacar:

  • Uso de versão ARG para Ruby, permitindo alterar facilmente a versão se necessário.

  • Remoção de caches de pacote após instalação, para deixar imagem mais enxuta.

  • Inclusão de configuração de timezone para evitar divergências em logs ou jobs crons.

# syntax=docker/dockerfile:1
# check=error=true

ARG RUBY_VERSION=3.4.5
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base
  
# Install dependencies
RUN apt-get update -qq && \
    apt-get upgrade -y && \
    apt-get install -y --no-install-recommends \
        build-essential \
        curl \
        git \              
        zsh \
        libpq-dev \
        htop \
        libyaml-dev \
        tzdata && \
    rm -rf /var/lib/apt/lists/* 

# Instalar Oh My Zsh sem pedir interação
RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended 

# Instalar Powerlevel10k
RUN git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/.oh-my-zsh/custom/themes/powerlevel10k && \
    sed -i 's/ZSH_THEME=".*"/ZSH_THEME="powerlevel10k\/powerlevel10k"/' ~/.zshrc

# Node.js + yarn
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
    && apt-get install -y nodejs \
    && npm install --global yarn \
    && yarn set version 1.22.1

# Timezone
ENV TZ=America/Recife
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# Rails app lives here
WORKDIR /app

# Copy only Gemfile and install gems
COPY Gemfile Gemfile.lock ./
RUN bundle install --jobs 4 --retry 4
  
# Copy the rest of the application code
COPY . . 

SHELL ["/bin/zsh", "-c"] 

# Start server
CMD ["bash", "-c", "bundle exec rails db:prepare && bundle exec rails server -b 0.0.0.0 -p 3000"]

3. Variáveis de Ambiente

Crie arquivos como .env.development (e .env.test etc) para definir variáveis como DATABASE_URL, REDIS_URL, RAILS_ENV, POSTGRES_USER, POSTGRES_PASSWORD, etc. Isso isola configurações específicas de ambiente do código, facilita alterações e mantém credenciais fora de versionamento.

  • Crie um arquivo chamado .env.development e adicione as variáveis:

REDIS_URL=redis://redis:6379/10
DATABASE_URL=postgres://postgres:postgres@db:5432/app_development
RAILS_ENV=development
  • Crie o arquivo .env, para configurar as variáveis de usario e senha do postgres:

POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
  • Crie o arquivo .env.test, para configurar as variáveis de ambiente para os testes:

DATABASE_URL=postgres://postgres:postgres@db:5432/app_test
RAILS_ENV=test

4. docker-compose.yml

O docker-compose.yml define os serviços necessários:

  • web (sua aplicação Rails)

  • db (PostgreSQL)

  • test (ambiente de teste)

  • redis (cache e backend para Sidekiq)

  • sidekiq (trabalhador de background)

Deve mapear portas apropriadas, dependências entre serviços, volumes para persistência de dados e compartilhamento de código para desenvolvimento.

services:

  redis:
    image: redis:7
    restart: always
    ports:
      - "6379:6379"

  worker:
     build:
       context: .
       dockerfile: ./worker/Dockerfile
     env_file:
       - ./.env.development
     volumes:
       - .:/app #diretório da aplicação

  db:
    image: postgres:15.7
    restart: always
    environment:
      POSTGRES_USER: ${POSTGRES_USER} # definido no arquivo.env
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # definido no arquivo.env
      POSTGRES_DB: app_development # banco do development localizado no database.yml
      TERM: xterm-256color
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  web:
    build: .
    stdin_open: true
    tty: true
    entrypoint: config/setup.sh
    command: bash -c "bin/rails tailwindcss:watch & bundle exec rails s -b 0.0.0.0 -p 3000"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db
    env_file:
      - ./.env.development

  test:
    build: .
    command: bash -c "RAILS_ENV=test bundle exec rails db:prepare && bundle exec rspec"
    volumes:
      - .:/app
    depends_on:
      - db
    env_file:
      - ./.env.test

volumes:
  postgres_data:

5. Configuração do database.yml

No Rails, configure database.yml para usar variáveis de ambiente (DATABASE_URL) sempre que possível, dentro do bloco default.

Isso permite reutilizar configurações entre ambientes (desenvolvimento, teste, produção) com menor duplicação.

Configure:

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  url: <%= ENV["DATABASE_URL"] %> # Variavél criada no env.development

development:
  <<: *default
  database: app_development # Nome do banco de desenvolvimento usando também no docker-compose.yml

6. Scripts de setup (.sh)

Crie scripts como config/setup_app.sh ou .sh em config que:

  • garantam que todas gems estejam instaladas (bundle install)

  • removam PID antigo de servidor, se existir

  • rodem migrações em ambientes que não sejam desenvolvimento

  • compilem ativos quando apropriado

  • finalmente executem o servidor ou comando desejado do container

Isso permite que o container se auto ajuste quando ligado ou reiniciado, e evita erros comuns de “PID já existe” ou migrações esquecidas.

  • Crie o arquivo setup.sh dentro do diretório config e adicione o código:

#! /bin/sh

set -e

bundle check || bundle install --jobs 5 --retry 5

if [ -f tmp/pids/server.pid ]; then
  rm tmp/pids/server.pid
fi

if [ "$RAILS_ENV" != "development" ]; then
  echo '--> Running migrations'
  rails db:migrate
  echo '--> end migrations'
  echo '--> Precompiling assets'
  rails assets:precompile
  echo '--> Cleaning assets'
  rails assets:clobber
else
  echo '--> Skiping assets precompilation on development'
fi

exec "$@" # executa o command do container
  • Depois execute o comando no terminal para dar permisão ao arquivo /config/setup.sh:

chmod +x config/setup.sh

7. Configurando Docker para sidekiq no Rails 8

  • Vamos configurar o worker que executará o Sidekiq. Primeiro, na raiz do projeto, crie um diretório chamado /worker. Em seguida, dentro desse novo diretório, crie um arquivo chamado Dockerfile.

  • Adicione o código:

# syntax=docker/dockerfile:1
# check=error=true

ARG RUBY_VERSION=3.4.5
FROM ruby:$RUBY_VERSION-slim

# Install dependencies
RUN apt-get update -qq && \
    apt-get upgrade -y && \
    apt-get install --no-install-recommends -y \
      build-essential \
      curl \
      libpq-dev \
      htop \
      libyaml-dev \
      tzdata && \
    rm -rf /var/lib/apt/lists/*

# Timezone
ENV TZ=America/Recife
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# Rails app lives here
WORKDIR /app

# Copy only Gemfile and install gems
COPY Gemfile Gemfile.lock ./
RUN bundle install --jobs 5 --retry 5

# Copy the rest of the application code
COPY . .

# Copy entrypoint script
COPY ./worker/entrypoint.sh /app/worker/entrypoint.sh
RUN chmod +x /app/worker/entrypoint.sh

# Start worker
CMD ["bash", "/app/worker/entrypoint.sh"]
  • agora vamos criar o arquivo entrypoint.sh dentro do diretório worker, para configurar o sidekiq e adicionar o código:

#!/bin/sh

set -e

exec bundle exec sidekiq -c 1#!/bin/sh

8. Configurando as rotas do sidekiq.

  • No arquivo routes adicione estas configurações:

require "sidekiq/web"
Rails.application.routes.draw do

 mount Sidekiq::Web => "/sidekiq" # monitoramento do sidekiq
end
  • Agora você vai conseguir monitorar o sidekiq na rota: http://127.0.0.1:3000/sidekiq

  • Adicione o código no seu development.rb para remover algumas mensagens do console relacionado ao sidekiq:

Rails.application.configure do
  config.web_console.whiny_requests = false
end

9. Passos de build e execução

  1. docker compose build – constrói as imagens conforme configurado.

  2. docker compose up – sobe os serviços conforme docker-compose.yml.

  3. Verifique se os containers estão ativos com docker ps.

  4. Caso necessário, entre no container da aplicação (docker exec -it <nome_do_container_web> bash) para criar banco e rodar migrações: rails db:create, rails db:migrate.

  • No termina na raiz do seu projeto rode o comando:

docker compose build
  • O Terminal deve retornar algo semelhante a imagem a baixo com a mensagem:

[+] Building 1/1
 ✔ web  Built   
screenshot do sistema
  • Agora para subir o servidor na porta 300 rode o comando:

docker compose up
  • Deve retornar algo semelhante a imagem com a mensagem de que o servidor esta na porta 3000:

Listening on http://0.0.0.0:3000
screenshot do sistema
  • Agora você pode abrir seu navegador na rota informada e deve retornar uma mensagem erro por falta de criação do banco de dados, algo semelhante a imagem:

screenshot do sistema

10. Criando migração no db dentro do Docker

  • após subir o servidor você pode verificar quais containers estão em execução, em um novo terminal sem fechar o terminal que subiu o docker rode o comando para saber o nome dos containers on:

docker ps
  • Este comando ovai retornar uma menagem no terminal semelhante a imagem a baixo, e no campo NAME vai ter o nome dos containers em execução, algo semelhante a imagem a baixo, se tiver criado o container de test ele também deve parecer:

screenshot do sistema
  • Agora acesse o container web que em nosso caso se chama app-web-1, para acesso digite o comando no terminal:

docker exec -it app-web-1 bash
  • Agora ao acessar o terminal do docker podemos criar nosso banco e rodar as migrações por lá com os comandos:

  • assim criamos o banco de dados:

bundle exec rails db:create
  • assim rodamos migrações no banco:

bundle exec rails db:migrate
  • Ao cria o banco de dados de retornar algo como:

screenshot do sistema
  • agora sim a página root do Rails 8 deve abrir em seu navegador:

screenshot do sistema

  • Rodando os testes

docker compose run --rm test

11. Finalização e próximos passos

Depois que tudo estiver funcionando no ambiente de desenvolvimento, você pode:

  • adicionar containers dedicados para workers (sidekiq)

  • configurar supervisão ou health checks

  • preparar configuração de produção (variáveis, segurança, assets etc...)

  • documentar como executar testes automatizados, lint e outras ferramentas de qualidade de código

Atualizado

Isto foi útil?