Raspberry Pi: Ruby on Rails & Nginx
10.05.2017Da ich mich die letzten Tage damit beschäftigt habe, wie ich Ruby on Rails-Anwendungen am besten zu Testzwecken auf meinem Raspberry Pi zum Laufen bekomme und dabei auf einige Entscheidungen und Schwierigkeiten gestoßen bin, möchte ich hier gerne eine kleine Hilfestellung für andere in meiner Situation geben.
Als Webserver verwende ich seit langem Nginx, da dieser in Verbindung mit PHP5-FPM zum Ausführen von PHP-Projekten wenig Leistung von einem ohnehin schon an Ressourcen stark begrenzten Raspberry Pi in Anspruch nimmt.
Zuvor verwendete ich Lighttpd, stieg allerdings aufgrund der doch eher langsameren Auslieferung von dynamischem Content auf dem Raspberry Pi (trotz vieler Performance-Anpassungen) auf Nginx um. Die Temperatur des Pis ist seitdem im normalen Betrieb mit PHP um ca. 2°C gesunken und meine Projekte laden spürbar etwas schneller.
Da ich nun auch gerne wieder mehr mit Rails machen wollte, musste ich mir überlegen, wie ich das am besten bei meinem aktuellen Setup umsetze. Die vermutlich einfachste Möglichkeit wäre, auf Apache 2 umzusteigen und das Passenger Apache 2 - Modul zu installieren. Das wäre allerdings auch mit einem Verlust meines geliebten Nginx einhergegangen. Jedem, der nicht dazu gezwungen ist oder aufgrund von persönlichen Preferenzen bei Nginx bleiben möchte, empfehle ich daher eher, auf Apache umzusteigen. Das Modulsystem vereinfacht vieles, auch für spätere Situationen. Nginx muss hingegen für jedes Modul mit sämtlichen Modulen, die benötigt werden, neu kompiliert werden.
Nach über einem halben Tag mit Versuchen, Passenger nicht als Ruby Gem zu installieren, um die Bedienung zu vereinfachen, und verschiedenen Lösungsansätzen der Passenger- und Nginx-Community, sowie den Versuchen, den bei Rails mitgelieferten Mini-Webserver oder Unicorn in Verbindung mit Nginx zu verwenden, kam ich dann gegen Abend endlich zu der scheinbar einzigen Möglichkeit, dies komfortabel zu verwirklichen.
Was ihr benötigt:
- Ruby (Unter Raspbian bereits vorinstalliert, ansonsten:
sudo apt-get install ruby
) - Rails (Wenn ihr euch hier befindet, solltet ihr Rails wohl schon installiert haben, ansonsten:
gem install rails
) - Ausreichend Ram (Nginx wird im weiteren Verlauf komplett neu kompiliert)
- Zeit...
Installation:
Im Grunde macht ihr erstmal nichts anderes, als in der offiziellen Installationsbeschreibung von Passenger beschrieben steht. Doch halt. Welche genau? Für den Raspberry Pi gibt es leider derzeit keine Möglichkeit, Passenger alleine zu installieren, ohne dabei Nginx neu kompilieren zu müssen. Nach einem Tag voller Versuche, kam ich zu dem Entschluss, dass auf dem Raspberry Pi scheinbar nichts daran vorbei führt, der Installationsanleitung zu folgen, um Passenger als Nginx-Modul zu installieren, was ein Kompilieren von Nginx erfordert.
Die originale Installationsanleitung findet ihr hier: https://www.phusionpassenger.com/library/install/nginx/install/oss/rubygems_norvm/
Zur Einfachheit führe ich hier noch mal die Schritte der englischen Installationsanleitung mit ein paar Ergänzungen auf.
Vorbereitung:
Um Passenger zu installieren, solltet ihr genug Ram zur Verfügung haben.
Da der Raspberry Pi 3 nur ~1 GB und andere Modelle sogar noch weniger Ram haben, ist es von Vorteil, das Swapping des Raspberry Pis wieder zu aktivieren, solltet ihr dies, wie ich, einmal deaktiviert haben, um SD-Schreibzugriffe einzusparen.
sudo systemctl start dphys-swapfile
Hinzu kommt, dass ihr möglicherweise den Ordner /tmp/ in den Ram ausgelagert habt. Die meisten, mich eingeschlossen, geben diesem Ordner nur geringen Speicher.
Kommentiert die Zeile für /tmp/ in eurer /etc/fstab - Datei aus und startet euer System neu.
sudo reboot
Schritt 1:
Sollte Nginx bereits installiert sein, muss dieser deinstalliert werden. Sichert hierzu lieber eure nginx.conf und die Ordner /etc/nginx/sites-available/ und /etc/nginx/sites-enabled/ z.B. in eurem Home-Ordner.
cd ~
mkdir nginx
cp /etc/nginx/nginx.conf nginx/nginx.conf
cp -R /etc/nginx/sites-available/ nginx/sites-available/
cp -R /etc/nginx/sites-enabled/ nginx/sites-enabled/
sudo apt-get purge nginx nginx-full nginx-light nginx-naxsi nginx-common
sudo rm -rf /etc/nginx
Schritt 2:
Passenger als Ruby Gem installieren.
Hierzu wird der folgende Befehl verwendet.
sudo gem install passenger --no-rdoc --no-ri
Schritt 3:
Kompilieren von Nginx mitsamt des Passenger-Moduls.
Stellt euch auf eine lange Wartezeit ein. Kocht schonmal das Essen für... die nächsten Tage...
Wenn ihr während der Installation gefragt werdet, in welchen Ordner Ihr Nginx installieren wollt, gebt ihr am besten der Einfachheit halber /etc/nginx an.
sudo passenger-install-nginx-module
Schritt 4:
Wenn ihr diesen Vorgang überstanden habt und euer Raspberry Pi dabei nicht überhitzt ist, solltet ihr sicherstellen, dass Passenger korrekt installiert wurde.
sudo passenger-config validate-install
Die darauffolgende Ausgabe sollte zwei Zeilen enthalten, an deren Ende jeweils ein Haken zu sehen ist, um zu symbolisieren, dass alles bisher korrekt gelaufen ist.
Außerdem ist jetzt der Moment gekommen, an dem ihr Swapping wieder deaktivieren könnt.
Hurra! Ihr habt es geschafft!
...die Installation zu überstehen... jetzt folgt die Einrichtung.
Einrichtung
Alles, was ab jetzt folgt, geht davon aus, dass ihr Nginx in den Ordner /etc/nginx installiert habt.
Im Verlauf dieses Abschnitts werdet Ihr eure neue Nginx-Installation um eure alten Konfigurationsdateien erweitern und so einrichten, dass Ihr eure Rails-Anwendungen über einen Unterordner-Alias aufrufen könnt, da es eher unwahrscheinlich ist, dass auf einem Raspberry Pi mehrere externe Domains und / oder Subdomains eingesetzt werden.
Schritt 1:
Kopiert eure vhost-Konfigurationen zurück ins neue Nginx-Verzeichnis.
Eure ursprüngliche nginx.conf - Datei könnt ihr ab jetzt lediglich zur Abgleichung bestehender Variablen in der neuen nginx.conf verwenden. Diverse Einstellungen, die ihr aus der alten Nginx Installation kennt, sind jetzt nicht mehr oder in geänderter Form verfügbar.
cp -R nginx/sites-available/ /etc/nginx/sites-available/
cp -R nginx/sites-enabled/ /etc/nginx/sites-enabled/
Schritt 2:
Bearbeitet die neue nginx.conf in /etc/nginx/conf/nginx.conf
sudo nano /etc/nginx/conf/nginx.conf
...und kommentiert zuallerst einmal den kompletten server {} - Block aus.
#server {
#listen 80;
#server_name localhost;
# [Alles dazwischen]
# deny all;
#}
Über dem server {} - Block fügt ihr folgende Zeile an, um eure alten vhost-Konfigurationen wieder verwenden zu können:
include /etc/nginx/sites-enabled/*;
Ganz oben in eurer nginx.conf ändert ihr zudem noch nach Bedarf die ersten Zeilen ab, damit diese in etwa der alten nginx.conf gleichen.
user www-data;
worker_processes 1;
error_log /var/log/nginx/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid /var/run/nginx.pid;
events {
worker_connections 768;
}
Nun könnt ihr die Datei wieder speichern.
Schritt 3:
Jetzt müsst ihr noch eurer gewünschten vhost-Datei einen weiteren Block hinzufügen, um eure Ruby on Rails-Anwendungen auch aufrufen zu können.
Bei mir ist das im Beispiel /etc/nginx/sites-enabled/default
#RailsApps
location ~ ^/Pfad-über-den-eure-App-erreichbar-sein-soll(/.*|$) {
alias /Pfad/zu/eurer/App/public$1;
passenger_base_uri /Name-der-App;
passenger_app_root /Pfad/zu/eurer/App;
passenger_document_root /Pfad/zu/eurer/App/public;
passenger_app_env development; #Auskommentieren, wenn sich eure Rails-App im Production-Status befindet.
passenger_enabled on;
}
Diesen Block könnt ihr nun für jede eurer Rails-Apps in abgeänderter Form wiederholen.
Sollte eure Datei noch eine zusätzliche IPv6 - listen-Angabe am Anfang der Datei haben, müsst ihr diese leider entfernen oder auskommentieren (und das selbe in jeder vhost-Datei wiederholen).
Diese Version von nginx unterstützt dies nicht und gibt ansonsten beim Versuch, Nginx zu starten, einen Fehler aus.
Herzlichen Glückwunsch, ihr solltet es nun geschafft haben!
Wie ihr Nginx startet, beendet, usw. erfahrt ihr wieder hier: https://www.phusionpassenger.com/library/install/nginx/install/oss/rubygems_norvm/#starting-nginx