Die neue Generation der Rails Server und vereine.ch

Vor 3 Jahren haben wir unser Produkt Citrin Rails Server aufgeschaltet. Diese vorkonfigurierten virtuellen Server bieten eine einfache Möglichkeit schnell und flexibel eine Ruby on Rails Applikation zu veröffentlichen.

Nun ist es soweit die nächste Generation der Rails Server vorzustellen. Hier eine kurze Übersicht der Neuerungen:

  • Basierend auf dem aktuellen Ubuntu LTS (14.04)
  • Probleme beim Server Reboot behoben
  • CSF vorinstalliert um Brute-Force Attacken auf Firewallebene zu verhindern
  • citrin gem mit logrotate autoconfig
  • Privater gitlab-Account für alle Rails Server Kunden

Wir wollen unseren Kunden die Möglichkeit geben ihren Rails Server aktuell zu halten*. Deshalb stellen wir bestehenden Kunden auf Anfrage kostenlos einen Rails Server der neuen Generation zur Verfügung und betreiben diesen bis zu einem Monat parallel zum Alten um diesen Zeit für die Migration der Applikation(en) zu geben.

  • Ubuntu 12.04 erhält nur noch bis 2017 Updates

Ich werde hier nun die Migration eines solchen Rails Servers anhand der vereine.ch Applikation beschreiben. Die Vereine App wurde mit den Standard-Tools des ursprünglichen Citrin Rails Servers deployed: Apache+Passenger, MySQL und Subversion als VCS.

Schritt 1: Der neue Server

Zuerst brauche ich natürlich Zugang zu einem neuen Rails Server für die Migration. Dazu habe ich einen solchen bei Citrin bestellt. Die einzige aussergewöhnliche Anforderung war, dass ich statt der neusten Ruby Version 1.9.3 als default konfiguriert haben wollte damit Passenger unter der gleichen Version läuft wie auch mein ursprüngliches System. Dank RVM ist es problemlos möglich verschieden Versionen parallel zu installieren und diese auch nachträglich zu wechseln.

Citrin stellt mir nun also einen neuen Server i8rh01 zur Verfügung und hinterlegt dort meinen public key im .ssh/authorized_keys des rails-dev Users.

Schritt 2: Das Subversion Repository auf git migrieren

Wer nicht Subversion verwendet kann diesen Schritt getrost überspringen.

Der ursprüngliche Rails Server kam mit Helper-Scripts zum erstellen von Subversion repositories auf dem Server direkt. Für die neue Generation haben wir uns entschieden jedem Rails Server Kunden auf Anfrage einen Account auf unserem gitlab Server zur Verfügung zu stellen. Hier also eine kurze Anleitung wie man das Subversion Repository zu git migriert.

Der erste Schritt soll in einem ausgecheckten Repository Verzeichnis ausgeführt werden.

svn log -q | awk -F '|' '/^r/ {sub("^ ", ", $2); sub(" $", ", $2); print $2" = "$2" <"$2">"}' | sort -u > authors-transform.txt

Nun die Datei authors-transform.txt um die E-Mail Addressen in <> ergänzen.

Als nächstes das git-svn tool installieren. Hier am Beispiel von Ubuntu.

aptitude install git-svn

Nun kann das Subversion Repository einfach als git Repository geklont werden.

git svn clone file:///svn/vereine [^] --no-metadata -A authors-transform.txt --stdlayout ~/temp

Nun noch die Definition der ignorierten Files übernehmen.

cd ~/temp
git svn show-ignore > .gitignore
git add .gitignore
git commit -m 'Convert svn:ignore properties to .gitignore.'

Als nächstes kann man über das gitlab Webinterface ein Repo für vereine.ch anlegen. URL und Zugangsdaten gibt es individuell bei Citrin.

git remote add origin git@gitlab01.citrin.ch:citrin/vereine.git
git push -u origin master

Schritt 3: Deployment

Im einfachsten Fall checkt man das Repository einfach auf dem neuen Server aus:

cd /var/www/rails_apps/prod
git clone git@gitlab01.citrin.ch:citrin/vereine.git

Falls sich nichts am Setup der Versionsverwaltung geändert hat kann man auch einfach den alten Application Root kopieren.

cd /var/www/rails_apps/prod
rsync -av rhXY.citrin.ch:/var/www/rails_apps/prod/vereine/ vereine/

In allen fällen soll schlussendlich die Rails Applikation unter /var/www/rails_apps/prod/vereine/ ausgecheckt sein.

Dort noch bundle install ausführen

cd /var/www/rails_apps/prod/vereine
bundle install --path vendor/bundle

Capistrano
Für vereine.ch verwende ich Capistrano als deployment Tool. Hier sind die Anpassungen die für das Deployment auf den neuen Server nötig waren.

Editieren: config/deploy.rb und 2 Zeilen manuell anpassen.

set :repository, "git@gitlab01.citrin.ch:citrin/vereine.git"
set :scm, :git

Der Rest lässt sich mit String-Replace anpassen

:%s/rh05/i8rh01

Schritt 4: Apache Konfiguration kopieren

Die Konfiguration die vom citrin gem der ersten Generation erstellt wurde ist kompatibel also kann das VirtualHost file einfach kopiert werden.

scp root@rh05.citrin.ch:/etc/apache2/sites-available/prod.vereine.conf /etc/apache2/sites-available/prod.vereine.conf 
cd /etc/apache2/sites-enabled
ln -s ../sites-available/prod.vereine.conf

Da vereine.ch auch unter https verfügbar ist habe ich auch die dazugehörige Konfiguration kopiert.

scp rh05.citrin.ch:/etc/apache2/sites-enabled/prod.vereine.conf_443 /etc/apache2/sites-enabled/prod.vereine.conf_443
scp rh05.citrin.ch:/etc/ssl/certs/vereine.ch.crt /etc/ssl/certs/vereine.ch.crt
scp rh05.citrin.ch:/etc/ssl/certs/vereine.ch.ca /etc/ssl/certs/vereine.ch.ca
scp rh05.citrin.ch:/etc/ssl/private/vereine.ch.key /etc/ssl/private/vereine.ch.key

Zudem mussten noch ein paar Apache Mods aktiviert werden.

cd /etc/apache2/mods-enabled
ln -s ../mods-available/ssl.conf 
ln -s ../mods-available/ssl.load 
ln -s ../mods-available/socache_shmcb.load
ln -s ../mods-available/rewrite.load

Schritt 5: MySQL Datenbank kopieren

Auf dem alten Server die Daten dumpen.

mysqldump -u vereine_prod -p vereine_prod > vereine.sql
scp vereine.sql i8rh01.citrin.ch:/tmp/

Auf dem neuen Server eine Datenbank erstellen und die Daten einlesen.

citrin create_database vereine
vi config/database.yml 
mysql -u vereine_prod -p vereine_prod < /tmp/vereine.sql

Die vereine.ch Applikation hat noch persistente Daten ausserhalb der Datenbank im Filesystem die ich ebenfalls Synchronisiert habe.

rsync -av root@rh05.citrin.ch:/var/www/rails_apps/prod/vereine/shared/system/ /var/www/rails_apps/prod/vereine/shared/system/

Schritt 6: Logrotate einrichten

Zuletzt lasse ich noch logrotate einrichten um zu verhindern, dass die Application Logs den Server vollschreiben.

citrin setup_logrotate vereine

Die Standardkonfiguration würde also den production log in /var/www/rails_apps/prod/vereine/log/ konfigurieren. Da die Vereine Applikation aber mit capistrano deployed wird muss ich noch den Pfad anpassen.

Die Datei /etc/logrotate.d/rails-app-vereine-prod editieren und

/var/www/rails_apps/prod/vereine/log/production.log {

ersetzen mit

/var/www/rails_apps/prod/vereine/shared/log/production.log {