Block > HabitRPG: Installation, Wartung, Tipps

In einem anderen Beitrag habe ich beschrieben, was HabitRPG ist und wozu und warum ich es nutze. Hier folgt nun eine detaillierte Beschreibung, wie HabitRPG lokal zum Laufen gebracht werden kann.

Die Gruende, warum ich HabitRPG lokal und nicht auf der normalen Website nutze:

Ok, los gehts! :)

Anleitungen fuer die lokale Installation mit Hilfe von Vagrant und unter Ubuntu befinden sich im Wiki von HabitRPG. Die Anleitung fuer Ubuntu gibt schon einige Sachen vor, aber ich will die einzelnen Schritte etwas genauer und an Arch Linux angepasst auflisten.

HabitRPG lokal aufsetzen

HabitRPG benoetigt im Hintergrund eine Datenbank, wobei sich hier fuer MongoDB entschieden wurde. Zudem basiert es unter anderem auf Node.js und die Menschen hinter HabitRPG haben ihren Code bei GitHub liegen. Also installieren wir erstmal die MongoDB, Node.js und Git mit folgendem Befehl (Quelle MongoDB):

# pacman -S mongodb nodejs git

Danach starten wir MongoDB (und lassen es optional bei jedem Systemstart starten).

# systemctl start mongodb
# systemctl enable mongodb # optional, startet MongoDB mit dem Systemstart

Update (2015-02-11): Es wurden etliche offene MongoDB Instanzen entdeckt. Bitte macht sicher, dass MongoDB nur fuer euch zugaenglich ist!

Nun koennen wir den Code von GitHub beziehen und wechseln anschliessend in das neue Verzeichnis, welches auch spaeter noch in einen anderen Ordner verschoben werden kann:

$ cd ~
$ git clone https://github.com/HabitRPG/habitrpg.git
$ cd habitrpg

Der Branch (Zweig) von Git sollte develop sein, das testen wir mit:

$ git branch

Der aktuelle Branch hat ein Stern (*) vor dem Namen. Wenn es nicht develop ist, wechseln wir in diesen Branch:

$ git checkout develop

Mit dem Paketmanager npm von Node.js installieren wir nun global (mit -g) grunt-cli und bower, daher folgendes mit Root-Rechten ausfuehren [Update (2015-03-07): phantomjs hinzugefuegt]:

# npm install -g grunt-cli bower phantomjs

Normalerweise sind die Rechte nun falsch gesetzt, daher passen wir die an, damit auch Leute ohne Root-Rechten die Programme nutzen koennen:

# chmod -R 755 /usr/lib/node_modules/{grunt-cli,bower,phantomjs}

Mit npm installieren wir jetzt noch die restlichen Abhaengigkeiten:

$ npm install

Wir sind fast fertig, es fehlt nur noch die Anpassung der Konfigurationsdatei. Dazu kopieren wir die Beispiel-Konfigurationsdatei:

$ cp config.json.example config.json

Und aendern das SESSION_SECRET in config.json, z.B. mit pwgen (ggf. mit pacman -S pwgen installieren). Der Rest der Datei kann so belassen werden.

$ pwgen -s 50 1

Die Datenbank sollte jetzt schon laufen (siehe oben, evtl. ueberpruefen mit systemctl status mongodb), also starten wir die Anwendung:

$ npm start

Im Browser rufen wir nun http://localhost:3000 auf. HabitRPG sollte nun dort zu sehen sein :)

Nun koennen wir uns anmelden (auf Play klicken und unter Register anmelden), oder ein schon vorhandenes Konto beim offiziellen HabitRPG exportieren und in der lokalen Instanz importieren. Die Anleitung dafuer befindet sich weiter unten.

HabitRPG updaten

Ab und zu gibt es am offiziellen HabitRPG Aenderungen, die dann natuerlich auch lokal genutzt werden koennen/sollten.
Dazu muessen wir folgende Schritte ausfuehren (Quelle):

Update (2015-07-02): Um das nicht immer manuell zu machen, habe ich ein kleines Skript geschrieben, was zumindest mal den Grossteil der Arbeit uebernimmt.

Datenexport und -import (zentral nach lokal)

Um ein schon vorhandenes Konto im offiziellen HabitRPG im lokalen zu nutzen, muessen die Daten erst exportiert werden. Dazu am Besten alle drei Dateien unter Export (history.csv, userdata.xml, userdata.json) herunterladen.
Da in den Daten kein Passwort vorhanden ist, kann ein temporaeres Passwort (in diesem Fall test) in userdata.json eingefuegt werden, um sich damit einloggen zu koennen. Das Passwort sollte danach direkt wieder geaendert werden!
Dazu die Datei userdata.json mit einem Texteditor oeffnen und die Zeile mit dem Wort email suchen. An das Ende der Zeile dann ein Komma anhaengen und folgendes in die naechsten zwei Zeilen schreiben:

"salt" : "f45185359d",
"hashed_password" : "b04475ce5a970087602f702ffec1af6e4a2eb73e"

Danach die Datei schliessen und mit folgendem Befehl in MongoDB importieren (zuerst gab es bei mir eine Fehlermeldung beim Import, daher am Besten noch --jsonArray anhaengen (Quelle)):

$ mongoimport --db habitrpg --collection users --file userdata.json --jsonArray

Nun kann sich ganz normal eingeloggt werden (mit dem Benutzernamen wie bei der offiziellen Version und dem Passwort test).

Datensicherung

Was manuell geht, geht natuerlich auch automatisch: die Sicherung der Daten.
Die koennen jetzt direkt per mongodump und einem Cronjob gesichert werden und ggf. per mongorestore wieder eingespielt werden.

$ mongodump --db habitrpg --out ~/backup

Der Cronjob koennte so aussehen:

$ crontab -e
@daily mongodump --db habitrpg --out $HOME/backup

Und die Backupdateien koennten dann z.B. in einem Gitrepository gesichert werden.

[An dieser Stelle schwand etwas meine Lust ;)]

Update (2014-07-18): Eingespielt werden koennen die Daten ueber folgenden Befehl (Quelle):

$ mongorestore --drop ~/backup/habitrpg

HabitRPG auf einem Server mit SSL aufsetzen

Das wollte ich heute (2014-07-18) mal nachholen, bin aber klaeglich gescheitert. Es existiert dafuer natuerlich wieder keine Doku, und auch herumprobieren (eher stochern) hat mich nicht weitergebracht.

Ueber jegliche Hilfe bin ich sehr dankbar! :)

Allerdings war mein erstes Problem, dass ich nichtmal die unverschluesselte Version mit Chromium aufrufen konnte, was an HSTS lag :(
Warum gibt es da nicht die Moeglichkeit, die Ports oder auch nur einzelne Ports/Subdomains zu ignorieren?
Naja, geloescht werden kann die jeweilige Domain in den Einstellungen von Chromium, dazu einfach folgendes in die Adressleiste eingeben (Quelle):

chrome://net-internals/#hsts

Unter “Delete domain” kann die Domain nun entfernt werden.

Update (2014-07-19): Hehe, neuer Tag, neues Glueck - so schnell gebe ich nicht auf ;)

Habe es nun hinbekommen. Den entscheidenden Tipp fand ich in diesem Blog, nach einer kurzen Suche nach “lighttpd npm” :)

Bei gleichbleibender config.json muss nur folgendes in die Konfigurationsdatei von lighttpd (siehe dazu auch mein Artikel zum absichern von lighttpd):

server.modules += ( "mod_proxy" )

$HTTP["host"] == "subdomain.domain.tld" {
    proxy.server = ( "" => ( (
        "host" => "127.0.0.1",
        "port" => "3000" )
    ) )
}

Und lighttpd neustarten:

systemctl restart lighttpd

Damit nun nicht mehr via http und Port 3000 auf HabitRPG zugegriffen werden kann, einfach den Port in der Firewall zumachen (Quelle) ;)

HabitRPG sollte auf dem Server am Besten unter einem extra User laufen, der z.B. so erstellt werden kann:

# useradd -d /home/habitrpg -s /bin/nologin habitrpg

Um direkt mit dem System zu starten, reicht bei systemd folgendes (z.B. in /etc/systemd/system/habitrpg.service):

[Unit]
Description=HabitRPG
After=syslog.target network.target

[Service]
Type=simple
User=habitrpg
WorkingDirectory=/home/habitrpg
ExecStart=/usr/bin/npm start
ExecStop=/usr/bin/npm stop

[Install]
WantedBy=multi-user.target

Aktivieren und starten dann mit folgenden Befehlen:

# systemctl enable habitrpg.service
# systemctl start habitrpg.service

Update (2014-08-17): Nach laengerem Laufen haben wir festgestellt, dass der Service das Log zuspammt (einzusehen via journalctl -e). Dies kann durch zwei Wege verhindert werden: alles nach /dev/null, also ins Nichts leiten oder HabitRPG im Produktivmodus laufen lassen (bisher lief es im Entwicklungsmodus). Update (2015-01-25): Laut paglias sollte HabitRPG nicht im Produktivmodus laufen, da zu viele externe Dienste eingebunden werden, die nur in der offiziellen Version benutzt werden. Dadurch failt in der lokalen Variante auch so vieles. Nutzung daher auf eigene Gewaehr.

Fuer beide Wege gilt: erst mal den Service stoppen:

# systemctl stop habitrpg.service

Ersteres laesst sich dann durch folgende ergaenzende Zeile (bei [Service]) in /etc/systemd/system/habitrpg.service bewerkstelligen:

StandardOutput=null

Zweiteres durch den Austausch der ExecStart-Zeile durch folgende Zeilen …

ExecStartPre=/home/habitrpg/node_modules/.bin/grunt build:prod
ExecStart=/home/habitrpg/node_modules/.bin/grunt nodemon

… und den Austausch der NODE_ENV-Zeile in /home/habitrpg/config.json durch folgende Zeile (also quasi development in production aendern):

"NODE_ENV":"production"

In beiden Faellen dann den Service neuladen und starten:

# systemctl daemon-reload
# systemctl start habitrpg.service

HabitRPG sollte nun nicht mehr das Log zuspammen und/oder im Produktivmodus laufen :)

Es war uebrigens wieder ein K®ampf, das alles herauszufinden, da der Produktivmodus ueberhaupt nicht dokumentiert ist ..
Letztendlich geholfen hat das Lesen des Codes (Gruntfile.js und Procfile) ..

Update (2014-11-13): Ein paar Mal hab ich inzwischen auf die neueste Version geupdated, dabei ist die best practice , den HabitRPG-Ordner zu verschieben (mv habitrpg habitrpg.bak-$(date +%F)), neu zu klonen (git clone https://github.com/HabitRPG/habitrpg.git), Abhaengigkeiten zu installieren (cd habitrpg ; npm install ; bower install) und die alte Konfigurationsdatei zu kopieren (cp ../habitrpg.bak-.../config.json .). Ggf. die Konfigurationsdatei an die neue Example-Datei anpassen (diff config.json config.json.example). oben beschrieben.
Beim jetzigen Mal wollte HabitRPG aber einfach nicht starten (weder mit npm start (und development) noch mit ./node_modules/.bin/grunt build:prod;./node_modules/.bin/grunt nodemon; (und production)). Der Fehler war dieser hier:

/home/habitrpg/node_modules/winston/lib/winston/logger.js:435
  var instance = created ? transport : (new (transport)(options));
                                        ^
TypeError: undefined is not a function
    at Logger.add (/home/habitrpg/node_modules/winston/lib/winston/logger.js:435:41)
    at Object.<anonymous> (/home/habitrpg/src/logging.js:11:16)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/home/habitrpg/src/server.js:7:15)
    at Module._compile (module.js:456:26)
[nodemon] app crashed - waiting for file changes before starting...

Ich hab nicht wirklich Ahnung vom Code, daher tippe ich einfach mal, dass das Problem an New Relic liegt, was ich aber nicht nutze (die Angaben in der Konfigurationsdatei habe ich so gelassen). Einfachster Weg ist hier, den Logger einfach nicht zu aktivieren. Dazu wird in der Datei src/logging.js folgende Zeile

logger.add(winston.transports.newrelic, {});

durch diese ersetzt:

// logger.add(winston.transports.newrelic, {});

Danach laesst sich HabitRPG wie gewohnt starten. Natuerlich habe ich auch diesmal nichts im Internet gefunden, und ich glaube auch, dass dieser Eintrag der einzige im Internet ist, der die Produktivinstallation von HabitRPG halbwegs nutzbar beschreibt (ausser vielleicht interne Firmendokumentationen ;)). Naja ;)

Update (2015-01-25): Ich hatte noch ein Problem mit dem Produktivmodus, den Bug und meinen Fix hab ich hier beschrieben (Quelle).
Update (2015-07-02): Heute wieder geupdated, der Fehler trat nicht mehr auf, damit habe ich das Issue geschlossen.

Erweiterte Rechte

Der Vorteil bei einer lokalen Installation ist nicht nur der Datenschutzaspekt, sondern auch die erweiterten Rechte ;)
So kann das eigene Konto mit Adminrechten und Edelsteinen ausgestattet werden, um alles machen zu koennen, was normalerweise Geld kostet. Das soll natuerlich nicht fuer alles genutzt werden, sonst macht das nicht mehr so viel Sinn ;)

Dazu folgende Schritte ausfuehren:

Meine Website waere ja langweilig, wenn es nicht noch ein bisschen geekiger gaenge, so bin ich eben ueber HabitRPG fuer die Kommandozeile gestolpert :D
Getestet habe ich es noch nicht, es steht aber als TODO in meiner lokalen HabitRPG-Instanz ;)

Zudem gibt es ja noch die mobile Variante, mit der ich dann auch auf meine eigene HabitRPG-Instanz zugreifen koennte. Da hab ich mich allerdings noch nicht drangewagt.

Geschrieben: 2015-01-25, 20:19 - Tags: linux, habitrpg