NginX + Mongrel -> Redmine

NginX + Ruby … hat bereits ein Tutorial auf adminwerk.de. Wem es in diesem Zusammenhang nichts ausmacht, mal eben schnell einen Webserver zu kompilieren, der findet dort eine stabile NginX/Ruby-Verbindung für die tägliche Arbeit. Wer allerdings unter Zeitdruck steht und gewiss keinen Webserver kompilieren möchte, der kommt hier mit NginX + Mongrel zum Zuge, wer möchte auch geclustert.

Vorarbeiten

Entsprechend den Installationshilfen auf redmine.org wird Redmine installiert und konfiguriert. Im Wesentlichen sind Abhängigkeiten zu installieren, einige Gems und die Datenbank wird initiiert. Auf der Howto-Seite des Projektes sind dazu diverse Anleitungen und Hilfen, sowie Versions abhängige Pakete. Nachfolgend wird davon ausgegangen, dass die Installation von Redmine steht.

Installation – Mongrel

Ausgehend davon, dass bereits eine lauffähige Ruby Umgebung existiert, wird im ersten Schritt Mongrel als gem installiert.

gem install mongrel mongrel_cluster

Im Anschluss gilt es diverse Verzeichnisse anzulegen in die nach allen Regeln der Kunst die Bestandteile des Servers verbracht werden.

  1. Konfigurationsverzeichnis unter /etc/mongrel  in das die entsprechenden Konfigurationen geschrieben werden.
    mkdir /etc/mongrel
  2. PID-Verzeichnis nach /var/run/mongrel mit Schreibzugriff für den Benutzer unter dem der Sever oder Cluster betrieben wird.
    mkdir /var/run/mongrel
    chown www-data.www-data /var/run/mongrel
  3. Log-Verzeichnis nach /var/log/mongrel mit Schreibzugriff für den Benutzer unter dem der Sever oder Cluster betrieben wird.
    mkdir /var/run/mongrel
    chown www-data.www-data /var/run/mongrel

Konfiguration – Mongrel Cluster

Die Konfiguration zur Nutzung von Redmine (geclustert!) wird im Folgenden erstellt und direkt nach /etc/mongrel_cluster/redmine-cluster.yml gesichert

mongrel_rails cluster::configure -e production -p 3000 \
                 -N 3 -c /path/to/redmine-root-directory \
                 -C /etc/mongrel_cluster/redmine-cluster.yml \
                 -a 127.0.0.1 --user www-data --group www-data \
                 -l /var/log/mongrel/mongrel.log \
                 -P /var/run/mongrel/mongrel.pid

Die erstellte Datei sieht dann wie folgt aus:

--- 
group: www-data
address: 127.0.0.1
log_file: /var/log/mongrel/mongrel-cluster.log
port: "3000"
cwd: /path/to/redmine
environment: production
user: www-data
pid_file: /var/run/mongrel/mongrel.pid
servers: 3

Startet noch nicht …?

Wer jetzt mit versucht den Cluster zu starten, der bekommt unter Umständen einen (oder auch keinen*) Fehler. Redmine Version 1.3.0 benötigt eine neuere rubygems-Version als die von Ubuntu Lucid zur Verfügung gestellte. Das Update mit Boardmitteln ist aber unter Ubuntu und Debian gesperrt – der Aufruf gem update --system erzeugt einen Fehler.

Weiter mit der Installation gelangt man nur dann, wenn man rubygems selbst aktualisiert:

wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz
tar xvf rubygems-1.3.7.tgz
cd rubygems-1.3.7
ruby setup.rb

Dieses Vorgehen macht es auch erforderlich diverse Gems (u.U.) neu zu installieren

gem install -v=2.3.14 rails
gem install mysql
gem install i18n
gem install rmagick
gem install rdoc -v=2.4.2

Die Installation des mysql-Gems benötigt unter zudem libmysqlclient16-dev. rmagick braucht die dev-Pakete von libmagick.

apt-get install libmysqlclient16-dev

Startet!

Das Absetzen von

mongrel_rails cluster::start -C /etc/mongrel/redmine-cluster.yml

funktioniert ab diesem Zeitpunkt, was die Ausgabe von netstat -antp | grep ruby zeigt:

tcp    0   0 127.0.0.1:3000    0.0.0.0:*   LISTEN   5581/ruby1.8
tcp    0   0 127.0.0.1:3001    0.0.0.0:*   LISTEN   5584/ruby1.8
tcp    0   0 127.0.0.1:3002    0.0.0.0:*   LISTEN   5587/ruby1.8

Herunterfahren kann man den Cluster mit

mongrel_rails cluster::stop -C /etc/mongrel/redmine-cluster.yml

Konfiguration – Mongrel Single

Es muss kein Cluster sein. Macht eigentlich auch nur begrenzt Sinn auf einem Standalone-Server (!). Soll einfach nur Redmine laufen empfiehlt sich der Start von Mongrel durch den Aufruf nachfolgenden Statements zu testen

mongrel_rails start -d -p 3000 -e production -c /path/to/redmine \
--user www-data --group www-data -P /var/run/mongrel/mongrel.pid \
-l /var/log/mongrel/mongrel.log

Weitere Informationen welche Parameter zum Starten übergeben werden können liefert

mongrel_rails mongrel::start -h

Analog gibt es Informationen wie der Server gestopt werden kann durch den Aufruf von

mongrel_rails mongrel::stop -h

Die Konfiguration der Einzel-Instanz kann von der Clusterkonfiguration kopiert und angepasst werden.

---
group: www-data
address: 127.0.0.1
log_file: /var/log/mongrel/mongrel.log
port: "3000"
daemon: true
cwd: /path/to/redmine/red
environment: production
user: www-data
pid_file: /var/run/mongrel/mongrel.pid

NginX bis zum Ende

Um den Mongrel-Cluster mit Nginx zu verbinden muss entsprechend die Konfiguration von Nginx erweitert werden. Die grundkonfiguration von Nginx sollte bereits existieren. Zunächst definiert man einen Upstream mit beliebigem Namen, auf den später mittels proxy_pass referenziert wird. Der Upstream liegt außerhalb des Server Konrtext.

upstream mongrel {
   server 127.0.0.1:3000;
   #server 127.0.0.1:3001; # für clusterbetrieb
   #server 127.0.0.1:3002; # für clusterbetrieb
}

Anschließend erfolgt eine Redmine spezifische Konfiguration des Servers, wie man sie leicht im Internet findet. Zum Beispiel:

server {
      ...
      root /path/to/redmine/public;
      location / {
         proxy_set_header        X-Real-IP       $remote_addr;
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header        host            $http_host;
         proxy_redirect          off;
         proxy_read_timeout      300;

         if (-f $request_filename/index.html) {
            rewrite (.*) $1/index.html break;
         }

         if (-f $request_filename.html) {
            rewrite (.*) $1.html break;
         }

         if (-f request_filename.txt) {
            rewrite (.*) $1.txt break;
         }

         proxy_pass          http://mongrel;
       }
       ...
}

Booten

In dieser Anleitung geht es lediglich darum Redmine mit Nginx/Mongrel an den Start zu bringen, respektiver irgendeine andere Rails App. Um Mongrel in den Bootprozess aufzunehmen habe ich ein Init-Skript in abgeänderter Form erstellt. Damit läßt sich gezielt die in dieser Anleitung erstellte Konfiguration einlesen. Das Skript wird nach /etc/init.d/mongrel installiert und mit chmod 755 /etc/init.d/mongrel angepasst. Das Skript startet den Server im Singlemodus. Wer den Clustermodus will, der kann die Variable CLUSTER auf „Y“ setzen.

#!/bin/sh
### BEGIN INIT INFO
# Provides:          mongrel
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Should-Start:      $network
# Should-Stop:       $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start mongrel server(s) at boot time
### END INIT INFO
#
# Copyright (c) 2007 Bradley Taylor, bradley@railsmachine.com
#               2012 Chris Möser, chris@adminwerk.de
#
# mongrel       Startup script for Mongrel (clusters).
#
# chkconfig: - 85 15
# description: mongrel manages one or multiple Mongrel processes for use \
#              behind a load balancer.
#
# Debianized by Filipe Lautert, filipe@icewall.org

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/mongrel_rails

DAEMON_CLUSTER="/usr/bin/mongrel_rails cluster::start"
DAEMON_KILL_CLUSTER="/usr/bin/mongrel_rails cluster::stop"

NAME=mongrel
DESC=mongrel

# Set this to Y to run a 3 entity cluster
CLUSTER="N"

test -x $DAEMON || exit 0

CONF_DIR=/etc/mongrel
PID_DIR=/var/run/mongrel
DAEMON_OPTS="-C $CONF_DIR/redmine.yml"
DAEMON_CLUSTER_OPTS="-C $CONF_DIR/redmine-cluster.yml"
DAEMON_KILL_PID="-P $PID_DIR/*.pid"

# Include mongrel defaults if available
if [ -f /etc/default/mongrel ] ; then
	. /etc/default/mongrel
fi

set -e

# if we do not have configuration files, skip the script
TOTAL_CONFS=$(ls $CONF_DIR | wc -l)
test $TOTAL_CONFS -ne 0 || exit 0

# Add user and group information, if specified
if [ -n "$USER" ]; then DAEMON_OPTS="$DAEMON_OPTS --user $USER"; fi
if [ -n "$GROUP" ]; then DAEMON_OPTS="$DAEMON_OPTS --group $GROUP"; fi

case "$1" in
  start)
	if [ "$CLUSTER" = "N" ]; then 
		mkdir -p $PID_DIR
	        chown $USER:$GROUP $PID_DIR
		echo -n "Starting $DESC: "
		start-stop-daemon --start --quiet \
			--exec $DAEMON -- start $DAEMON_OPTS
		echo "$NAME."
	else 
		mkdir -p $PID_DIR
			chown $USER:$GROUP $PID_DIR
		echo -n "Starting $DESC cluster: "
		start-stop-daemon --start --quiet \
			--exec $DAEMON_CLUSTER -- start $DAEMON_CLUSTER_OPTS
		echo "$NAME."		
	fi
	;;
  stop)
	if [ "$CLUSTER" = "N" ]; then 
		echo -n "Stopping $DESC: "
		start-stop-daemon --start --quiet \
			--exec $DAEMON -- stop $DAEMON_KILL_PID
		echo "$NAME."
	else
		mkdir -p $PID_DIR
			chown $USER:$GROUP $PID_DIR
		echo -n "Stopping $DESC cluster: "
		start-stop-daemon --start --quiet \
			--exec $DAEMON_KILL_CLUSTER -- stop $DAEMON_CLUSTER_OPTS
		echo "$NAME."		
	fi
	;;
  *)
	N=/etc/init.d/$NAME
	echo "Usage: $N {start|stop}" >&2
	exit 1
	;;
esac
exit 0

Fehlt noch

update-rc.d mongrel defaults

und dem Start zur Bootzeit sollte nichts mehr im Wege stehen.

*) Keinen dann, wenn der Aufruf gar nichts zurückgibt, kein Logfile schreibt, usw. => &%$@-ärgerlich!


Beitrag veröffentlicht

in

, , , ,

von

Schlagwörter:

Kommentare

Schreibe einen Kommentar