Rails

Rails

Deploye eine Rails-App mit Postgres, Workers, Solid Queue, Tailwind-Assets und zusätzlichen Rails-8-Datenbanken.

  • Release: bin/rails db:prepare läuft, bevor jede Version live geht (dein Procfile-release: gewinnt).
  • Produktions-Defaults: RAILS_ENV, RACK_ENV, RAILS_SERVE_STATIC_FILES und RAILS_LOG_TO_STDOUT werden gesetzt, falls du es nicht getan hast; Assets werden mit SECRET_KEY_BASE_DUMMY=1 gebaut, sodass beim Build kein echtes Secret nötig ist. SECRET_KEY_BASE wird einmal generiert.
  • Datenbanken: pg → Postgres, mysql2/trilogy → MySQL, redis/sidekiq → Redis. Zusätzliche Rails-8-Datenbanken (cache, queue, cable), die in config/database.yml gefunden werden, bekommen jeweils ihre eigene <NAME>_DATABASE_URL.
  • Workers: Sidekiq, Solid Queue (bin/jobs, falls vorhanden), GoodJob, Resque und Delayed Job werden aus deiner Gemfile.lock angeboten.
  • Uploads: Active Storage auf Disk bekommt automatisch ein persistentes storage/-Volume; oder hänge einen Bucket an, dann werden die S3-Variablen injiziert.
  • Alte native Gems (nio4r, puma 5…) kompilieren unverändert unter GCC 14.

Workers sind ein zweiter Prozess, keine zweite App

Eine App ist eine Codebasis und ein Image; web, worker, der Release-Befehl und Cron sind Prozesstypen derselben App, jeder für sich skaliert — das 12-Factor-Modell, keine Flotte fast identischer Apps für eine Codebasis. Mit einem Procfile:

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

erscheinen beide automatisch. Ohne eines startet Railyard web selbst und bietet den ersten Job-Runner, den es in deiner Gemfile.lock findet, als worker-Prozess an. Füge weitere im Workers-Tab der App hinzu, oder skaliere die vorhandenen über die CLI:

railyard scale my-app worker=3

web ist vorerst auf eine Replika begrenzt; worker skaliert von 1 bis 10. Siehe Workers und geplante Jobs für Cron.

Solid Queue, auf drei Arten

  • Eigene Datenbank (der Rails-8-Standard). config/database.yml deklariert einen queue:-Eintrag mit migrations_paths: db/queue_migrate; Railyard liest das als zusätzliche Datenbank und stellt neben DATABASE_URL eine separate QUEUE_DATABASE_URL bereit. bin/rails db:prepare migriert beide im Release-Schritt. Der Worker-Prozess führt bin/jobs aus, falls deine App das hat, sonst bundle exec rake solid_queue:start.
  • Gemeinsame Nutzung der primären Datenbank. Entferne den queue:-Eintrag (oder zeig ihn auf die primäre Verbindung) und die Tabellen von Solid Queue liegen neben deinen eigenen — es wird nichts zusätzlich bereitgestellt, eine DATABASE_URL, derselbe Worker-Befehl.
  • Innerhalb von Puma, kein Worker-Prozess. Der Schalter Run Solid Queue inside Puma im Canvas-Panel Settings → Rails setzt SOLID_QUEUE_IN_PUMA=true, was eine Standard-Rails-8-config/puma.rb bereits liest (plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"]). Puma verteilt die Jobs selbst; entferne den worker-Prozess und skaliere stattdessen web.

Dasselbe Panel fügt Action Cable auf Solid Cable hinzu (WebSockets, was eine eigene CABLE_DATABASE_URL bereitstellt), YJIT und Thruster vor Puma.

Konfiguration und Secrets

Nichts außer Env-Variablen: setze eine unter Variables, oder per railyard env:set my-app KEY=VALUE über die CLI, und dasselbe Image läuft unverändert von Staging bis Produktion — Dev/Prod-Parität, kein Build-Time-Branch. SECRET_KEY_BASE und jedes andere Secret, das deiner App gehört, werden einmal generiert und verschlüsselt; ein Drittanbieter-Key wird nie für dich erfunden. Um auf ein Postgres oder Redis zu verweisen, das als eigener Service auf dem Canvas läuft statt als Addon auf dem Server der App, referenziere es mit ${{redis.REDIS_URL}} — wird pro Umgebung aufgelöst, dieselbe Cross-Service-Syntax, die überall verwendet wird. Siehe Variablen und Secrets.

Assets vorkompilieren (Tailwind, esbuild, importmap)

assets:precompile läuft im Build-Schritt ganz ohne Einrichtung von dir: Der Build verdrahtet eine Node-Toolchain direkt in den Ruby-Build, sodass ein daran angehängter tailwindcss:build- oder cssbundling-rails/esbuild-Schritt einfach funktioniert — es ist keine separate Dockerfile-Stage oder Pre-Deploy-Hook nötig. Wenn das Precompiling die Datenbank oder Redis braucht — etwa ein Initializer, der beim Boot abfragt — und nur der App-Server die hat, bemerkt Railyard den Fehlschlag dort und verschiebt genau diesen Schritt automatisch in die Release-Phase, wo sie existieren. Ein bereits fertig gebautes Image zu pushen statt es Railyard bauen zu lassen, funktioniert genauso: Assets werden zuerst gegen Wegwerf-Container von Postgres und Redis auf dem Build-Server kompiliert und ins Image gebacken, bevor es den App-Server erreicht, sodass deine echte Datenbank nie berührt wird. Dafür brauchst du keinen release_command — setze einen nur, wenn db:prepare nicht ausreicht, z. B. ein Datenmigrationsskript.

Deployen

  • Aus einem Repo: füge die Git-URL ein, oder wähle es aus der Liste, sobald GitHub verbunden ist — Railyard liest das Gemfile, trägt die Prozessliste, Datenbanken und dokumentierten Variablen ein und deployt bei jedem Push.
  • Über die CLI: railyard create my-app https://github.com/me/my-app --addons postgres,redis, oder führe railyard git:remote && git push railyard main im Repo aus, um ohne GitHub bei jedem Push zu deployen.
  • Mit einem Klick: füge den Deploy-Button zu deiner README hinzu, oder veröffentliche im Template-Katalog, damit jeder es mit bereits ausgefüllten Addons und Variablen starten kann.