Rails

Rails

Faça deploy de um app Rails com Postgres, workers, Solid Queue, assets Tailwind e os bancos de dados extras do Rails 8.

  • Release: bin/rails db:prepare roda antes de cada versão entrar no ar (a linha release: do seu Procfile tem prioridade).
  • Padrões de produção: RAILS_ENV, RACK_ENV, RAILS_SERVE_STATIC_FILES e RAILS_LOG_TO_STDOUT são definidos se você não tiver feito isso; os assets são buildados com SECRET_KEY_BASE_DUMMY=1, então um secret real não é necessário em tempo de build. O SECRET_KEY_BASE é gerado uma única vez.
  • Bancos de dados: pg → Postgres, mysql2/trilogy → MySQL, redis/sidekiq → Redis. Bancos de dados extras do Rails 8 (cache, queue, cable) encontrados em config/database.yml recebem cada um sua própria <NAME>_DATABASE_URL.
  • Workers: Sidekiq, Solid Queue (bin/jobs quando presente), GoodJob, Resque e Delayed Job são oferecidos a partir do seu Gemfile.lock.
  • Uploads: Active Storage em disco recebe automaticamente um volume persistente em storage/; ou conecte um bucket e as variáveis do S3 são injetadas.
  • Gems nativas antigas (nio4r, puma 5…) compilam sob o GCC 14 sem alterações.

Workers são um segundo processo, não um segundo app

Um app é um único código-fonte e uma única imagem; web, worker, o comando de release e o cron são tipos de processo desse mesmo app, cada um escalado separadamente — o modelo 12-factor, não uma frota de apps quase idênticos para um único código-fonte. Com um Procfile:

web: bin/rails server -p $PORT
worker: bundle exec sidekiq

os dois aparecem automaticamente. Sem um, o Railyard inicia o web por conta própria e oferece o primeiro executor de jobs que encontrar no seu Gemfile.lock como processo worker. Adicione mais na aba Workers do app, ou escale o que já existe pela CLI:

railyard scale my-app worker=3

O web fica limitado a uma réplica por enquanto; o worker escala de 1 a 10. Veja Workers e jobs agendados para cron.

Solid Queue, de três jeitos

  • Banco de dados próprio (o padrão do Rails 8). O config/database.yml declara uma entrada queue: com migrations_paths: db/queue_migrate; o Railyard lê isso como um banco de dados extra e provisiona uma QUEUE_DATABASE_URL separada, junto da DATABASE_URL. O bin/rails db:prepare migra os dois na etapa de release. O processo worker roda bin/jobs se o seu app tiver esse arquivo, ou então bundle exec rake solid_queue:start.
  • Compartilhando o banco de dados principal. Remova a entrada queue: (ou aponte ela para a conexão principal) e as tabelas do Solid Queue vivem junto das suas — nada extra é provisionado, uma única DATABASE_URL, mesmo comando de worker.
  • Dentro do Puma, sem processo worker. O switch Run Solid Queue inside Puma, no painel Settings → Rails do canvas, define SOLID_QUEUE_IN_PUMA=true, que um config/puma.rb padrão do Rails 8 já lê (plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"]). O próprio Puma despacha os jobs; remova o processo worker e escale o web em vez dele.

O mesmo painel adiciona o Action Cable sobre Solid Cable (WebSockets, que provisiona sua própria CABLE_DATABASE_URL), o YJIT e o Thruster na frente do Puma.

Configuração e secrets

Nada além de variáveis de ambiente: defina uma em Variables, ou railyard env:set my-app KEY=VALUE pela CLI, e a mesma imagem roda sem alterações de staging até produção — paridade dev/prod, não um branch em tempo de build. O SECRET_KEY_BASE e qualquer outro secret que o seu app gera são criados uma única vez e criptografados; uma chave de terceiros nunca é inventada para você. Para apontar para um Postgres ou Redis rodando como serviço próprio no canvas, em vez de um addon no servidor do app, referencie com ${{redis.REDIS_URL}} — resolvido por ambiente, a mesma sintaxe entre serviços usada em todo lugar. Veja Variáveis e secrets.

Precompilando assets (Tailwind, esbuild, importmap)

O assets:precompile roda na etapa de build sem nenhuma configuração sua: o build já integra um toolchain Node dentro do próprio build Ruby, então uma etapa tailwindcss:build ou cssbundling-rails/esbuild encadeada nele simplesmente funciona — não existe um estágio separado de Dockerfile ou um hook pré-deploy para escrever. Se a precompilação precisar do banco de dados ou do Redis — um initializer que consulta algo no boot, por exemplo — e só o servidor do app tiver esses recursos, o Railyard percebe a falha ali e adia essa mesma etapa para a fase de release automaticamente, onde eles existem. Enviar uma imagem já pronta em vez de deixar o Railyard buildar funciona do mesmo jeito: os assets são compilados contra containers descartáveis de Postgres e Redis no servidor de build primeiro, e são embutidos na imagem antes dela chegar ao servidor do app, então o seu banco de dados real nunca é tocado. Você não precisa de um release_command para nada disso — defina um só se o db:prepare não for suficiente, por exemplo um script de migração de dados.

Fazendo o deploy

  • A partir de um repositório: cole a URL do Git, ou escolha no seletor depois que o GitHub estiver conectado — o Railyard lê o Gemfile, preenche a lista de processos, os bancos de dados e as variáveis documentadas, e faz deploy a cada push.
  • Pela CLI: railyard create my-app https://github.com/me/my-app --addons postgres,redis, ou rode railyard git:remote && git push railyard main dentro do repositório para fazer deploy a cada push sem precisar do GitHub.
  • Um clique só: adicione o botão de deploy ao seu README, ou publique no catálogo de templates para qualquer pessoa lançar com os addons e variáveis já preenchidos.