Mehrere Rails-Anwendungen pro VHost auf Lighttpd

Wer es schonmal versucht hat, Ruby on Rails unter Lighttpd zum Laufen zu bekommen, wird wissen, daß dies im Prinzip super einfach ist. Sobald man aber eine Rails-Anwendung in einem Unterverzeichnis der Domain laufen lassen möchte, bekommt man gewaltige Kopfschmerzen. Alle googlebaren Tricks führen entweder dazu, daß man beim Deployment Code ändern muß, böse Hacks in den Routen vornehmen muß oder an Stellen Hack’s einbaut, die nicht nötig sind.

Sogar Lighttpd selbst bringt einen solchen Hack mit, der beim Request das Prefix von der URL entfernt und dem Rails-Dispatcher so vorgauckelt, er würde im Hauptverzeichnis laufen. Dies führt zwar dazu, daß die Routen richtig erkannt werden, dafür muß bei allen Links in den Templates das Prefix manuell ergänzt werden. Kategorie: Buh! *thumbsdown* Die Idee war für mich gestorben.

Der nächste Hack führt eine Variable ein, die je nach Situation im Rails-Quellcode entweder gesetzt oder eben wieder gelöscht wird, um den Routen-Generator und den Routen-Parser zu überlisten. Auf so einen Blödsinn hatte ich keine Lust.

Nach dem Studium des Quellcodes fand ich heraus, daß es eine Variable RAILS_RELATIVE_URL_ROOT gibt, die man im Environment selbst setzen kann und die unter Apache sogar per Autodetect durch Rails selbst gesetzt wird. Weil Lighttpd aber etwas anders funktioniert, ist das dort nicht einsetzbar.

Anders gesprochen: Wenn ich also diese Variable händisch setze, müßte Rails ja damit klar kommen. Ist leider nicht so, Rails weiß überhaupt nichts davon, daß diese Variable gesetzt ist, wenn man den dokumentierten Weg für die Einstellungen des FCGI-Servers geht:

9 fastcgi.server = (
10   ".fcgi" => (
11     "localhost" => (
12       "min-procs" => 1,
13       "max-procs" => 5,
14       "socket" => approot + appname + "/tmp/lighttpd.socket",
15       "bin-path" => "/usr/bin/ruby " + approot + appname + "/public/dispatch.fcgi",
16       "bin-environment" => ( "RAILS_ENV" => "production", "RAILS_RELATIVE_URL_ROOT" => "/" + appname ))))

Dies ist wegen einer schlecht dokumentierten Eigenschaft des FCGI-Protokolls zum Scheitern verurteilt, da der Rails-FCGI-Dispatcher zum Zeitpunkt der Ausführung keinen Zugriff auf diese Variable mehr hat. Der Trick ist, die Variable aus dem „bin-environment“-Array herauszunehmen und mit dem Lighttpd-Modul „mod_setenv“ zu setzen. Der komplette Code-Schnippsel für die Rails-Konfiguration in Lighttpd sieht dann wie folgt aus:

5 server.error-handler-404 = "/" + appname + "/dispatch.fcgi"
6 alias.url = ( "/" + appname => approot + appname + "/public" )
7 index-file.names = ( "index.html", "dispatch.fcgi" )
8 setenv.add-environment = ( "RAILS_RELATIVE_URL_ROOT" => "/" + appname )
9 fastcgi.server = (
10   ".fcgi" => (
11     "localhost" => (
12       "min-procs" => 1,
13       "max-procs" => 5,
14       "socket" => approot + appname + "/tmp/lighttpd.socket",
15       "bin-path" => "/usr/bin/ruby " + approot + appname + "/public/dispatch.fcgi",
16       "bin-environment" => ( "RAILS_ENV" => "production" ))))

Den etwas umständlichen „bin-path“-Aufruf führe ich so aus, damit sich Grsec und PaX im Kernel eines Hardened-Linux nicht über Ausführungsrechte in einem potentiell unsicheren Verzeichnis beschweren. Andere Lighttpd-Rails-Beispiele im Netz starten hier direkt den FCGI-Dispatcher ohne den Interpreter explizit anzugeben. Die Variablen „approot“ und „appname“ sind vorher entsprechend zu besetzen. Auch „server.document-root“ sollte noch richtig gesetzt werden (passiert bei mir in einer seperaten Config-Datei und fehlt hier deshalb).

2 Antworten to “Mehrere Rails-Anwendungen pro VHost auf Lighttpd”

  1. Jens Says:

    Interessanter Artikel. In welcher Konstellation benötigst du mehrere Railsapps in einem Verzeichnis? Wären nicht Subdomains eine sauberere Lösung.

    Gruß Jens

  2. hurikhan77 Says:

    Es geht nicht unbedingt darum, mehrere Rails-Apps in einem Verzeichnis/VHost unterzubringen, sondern hauptsächlich darum, diese in einem Unterverzeichnis des VHosts laufen zu lassen als Ergänzung/Erweiterung zu bestehenden Webpräsenzen. Als Nebeneffekt lassen sich dann natürlich auch mehrere Rails-Apps in einem VHost unterbringen – was z.B. an meinem Arbeitsplatz wichtig ist, bei dem Demo-Anwendungen und verschiedene Tools auf einem VHost entwickelt werden und viele – da intern genutzt – diese nie diesen Platz verlassen.


Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: