Sonntag, 27. März 2016
Als Projekt für das Oster-Wochenende habe ich mir die Installation eines Dokumentenmanagementsystems (DMS) vorgenommen. Ziel ist es, die von mir seit Jahren gescannten Einkaufsbelege sauber in einem Archiv abzulegen und die Belege anschliessend mit meiner selbstprogrammierten Buchhaltungs-Applikation (PHP/MySQL) zu verknüpfen.
Nach einem wenig erfolgsversprechenden Umweg über Alfresco (zu gross, zu komplex, beansprucht zu viele Ressourcen) landete ich schlussendlich bei Sismics Docs, auch wenn dieses in einer Übersicht quelloffener DMS aus dem Jahr 2010 nicht erwähnt wird. Die Screenshots haben mich überzeugt, die Software zu installieren und herunterzuladen.
Da ich mich nicht mit Java-Applikationen auskenne, liefere ich hier eine Installationsanleitung. Sie richtet sich an Personen, welche ausreichend Linux-Erfahrung haben, anstelle aus der Java- aber aus der PHP/MySQL-Ecke kommen.
Repository auschecken
Als erstes legen wir uns eine lokale Kopie des Git-Repositories an:
# mkdir /usr/local/bin/sismics
cd /usr/local/bin/sismics
git clone https://github.com/sismics/docs.git .
To Dock or not to Dock
Unter den Dateien des Repositories finden sich Hinweise darauf, dass der Entwickler Docker zu verwenden scheint; u.a. existieren im Wurzelverzeichnis des Repositories die Dateien Dockerfile, build.sh und run-service.sh.
Ich konnte das Teil mit Docker aber nicht zum Laufen bringen. Dies aus mehreren Gründen:
i686
Der kräftigere meiner beiden Linux-Server, welcher im Elternhaus läuft, hat Debian i686 installiert, ein 32-bit Linux. Docker erfordert x86_64 (64-bit). Ein forciertes Upgrade tönt nach digitalem Selbstmord.
Die Bit-Architektur überprüfen kann man dies mit folgendem Befehl:
$ uname -m
x86_64
Docker installieren
Der Intel NUC, welcher in unserer Mietwohnung im Netzwerk hängt, hat ein x86_64 Linux am Laufen. Deshalb führte ich dort die Installation gemäss der offiziellen Anleitung aus.
Vorgängig musste ich noch herausfinden, welche Debian-Version ich installiert hatte:
# lsb_release -da
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.3 (jessie)
Release: 8.3
Codename: jessie
Quelle: Check what Debian version you are running on your Linux system
Jessie! Anschliessend folgte ich der offiziellen Anleitung:
# apt-get install apt-transport-https ca-certificates
# apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
# echo "deb https://apt.dockerproject.org/repo debian-jessie main" > /etc/apt/sources.list.d/docker.list
# apt-get update
# apt-get install docker-engine
# service docker start
# docker run hello-world
Bingo, Docker läuft.
Image nicht gefunden
Leider funktioniert die Generierung des Images für das Sismics Docs nicht:
# cd /usr/local/bin/sismics
# docker build -t sismics:0.1 .
Sending build context to Docker daemon 14.35 MB
Step 1 : FROM sismics/debian-java7-jetty9
Pulling repository docker.io/sismics/debian-java7-jetty9
Error: image sismics/debian-java7-jetty9 not found
Mit dem Switch -t definiert man das Paket und den Tag (vgl. Docker — build.
*seufz* Okey, dann halt kein Docker.
Manuelle Installation
Nun gut, da wir den Docker-Weg nicht beschreiten können, verlassen wir den Intel NUC und wenden uns wieder dem kräftigeren Server zu.
Pakete
Damit man schon nur die Testumgebung des DMS hockriegt, benötigt man folgende Pakete:
# apt-get install maven tesseract-ocr openjdk-7-jdk
Testinstallation bauen
Sobald die Pakete auf dem Rechner liegen, bauen wir uns die Testinstallation:
# cd /usr/local/bin/sismics/docs-parent
# mvn clean -DskipTests install
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Docs Parent ........................................ SUCCESS [ 7.114 s]
[INFO] Docs Core .......................................... SUCCESS [01:37 min]
[INFO] Docs Web Commons ................................... SUCCESS [ 47.086 s]
[INFO] Docs Web ........................................... SUCCESS [ 30.833 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 03:02 min
[INFO] Finished at: 2016-03-27T09:52:29+00:00
[INFO] Final Memory: 34M/94M
[INFO] ------------------------------------------------------------------------
Testinstallation starten
Nun starten wir die Testinstallation, um zu sehen, ob alles wie gewünscht funktioniert:
# cd /usr/local/bin/sismics/docs-web
mvn jetty:run
...
[INFO] Started ServerConnector@b40c2f{HTTP/1.1}{0.0.0.0:8080}
[INFO] Started @23372ms
[INFO] Started Jetty Server
Sobald diese Anzeige erscheint, können wir mit einem Web-Browser auf den Applikationsserver zugreifen:
10.1.2.3:8080/docs-web/src/
Das Standardpasswort des Administrator-Kontos lautet admin, wie eine Suche durch den Quellcode offenbart:
$ ack passw
...
docs-core/src/main/java/com/sismics/docs/core/constant/Constants.java
19: * Administrator's default password ("admin").
...
Java Advanced Imaging
Die Web-Oberfläche funktioniert, man kann Dateien hochladen — doch ausgerechnet das erste PDF produzierte folgende Fehlermeldung im Log der Applikation:
Cannot read JPEG2000 image: Java Advanced Imaging (JAI) Image I/O Tools are not installed
Diese Tools installiert man sich folgendermassen:
$ cd /tmp
$ wget "https://install-java-jai-imageio.googlecode.com/files/install-java-jai-imageio"
# bash /tmp/install-java-jai-imageio
Quelle: Install Java Advanced Imaging ImageIO Tools on a Linux Machine
ACHTUNG: Bitte den Inhalt aller aus dem Netz heruntergeladenen Bash-Scripts gründlich prüfen, bevor man sie unter dem root-Account ausführt.
Weitere Pakete installieren
Rückblickendes Ziel meines Sonntagsprojekts war es, die Applikation unter dem Java-Applikationsserver Jetty persistent zum Laufen zu bringen. Hierzu bauen wir uns ein sog. war-File. Damit das auch sauber funktioniert, benötigen wir folgende Pakete:
# apt-get install nodejs npm
# ln -s /usr/bin/nodejs /usr/bin/node
# npm install -g grunt-cli
Wir sehen, ob alle nötigen Komponenten da sind, wenn folgende Befehle einen Wert zurückgeben:
$ which node
/usr/bin/node
$ which grunt
/usr/local/bin/grunt
Insbesondere das node-Binary ist zwingend nötig — bei den ersten Kompilationsversuchen erschien folgende Fehlermeldung …
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Docs Web 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ docs-web ---
[INFO] Deleting /usr/local/bin/sismics/docs-web/target
[INFO]
[INFO] --- maven-antrun-plugin:1.8:run (default) @ docs-web ---
[INFO] Executing tasks
building:
[exec] /usr/bin/env: ‘node’: No such file or directory
[exec] Result: 127
[INFO] Executed tasks
[INFO]
[INFO] --- maven-resources-plugin:2.7:resources (default-resources) @ docs-web ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO] Copying 1 resource
...
… und ich endete mit einem nur halbwegs funktionsfähigen .war, weil bestimmte nodejs-Komponenten fehlten:
building:
[exec] /usr/bin/env: ‘node’: No such file or directory
[exec] Result: 127
Der oben angelegte Symlink löst dieses Problem:
...
building:
[exec] Running "clean:dist" (clean) task
[exec]
[exec] Running "ngmin:dist" (ngmin) task
[exec] ngminifying src/app/docs/app.js, src/app/docs/controller/Login.js, src/app/docs/controller/Main.js, src/app/docs/controller/Navigation.js, src/app/docs/controller/document/Document.js, src/app/docs/controller/document/DocumentDefault.js, src/app/docs/controller/document/DocumentEdit.js, src/app/docs/controller/document/DocumentModalPdf.js, src/app/docs/controller/document/DocumentModalShare.js, src/app/docs/controller/document/DocumentView.js, src/app/docs/controller/document/DocumentViewActivity.js, src/app/docs/controller/document/DocumentViewContent.js, src/app/docs/controller/document/DocumentViewPermissions.js, src/app/docs/controller/document/FileModalView.js, src/app/docs/controller/document/FileView.js, src/app/docs/controller/settings/Settings.js, src/app/docs/controller/settings/SettingsAccount.js, src/app/docs/controller/settings/SettingsDefault.js, src/app/docs/controller/settings/SettingsGroup.js, src/app/docs/controller/settings/SettingsGroupEdit.js, src/app/docs/controller/settings/SettingsLog.js, src/app/docs/controller/settings/SettingsSecurity.js, src/app/docs/controller/settings/SettingsSecurityModalDisableTotp.js, src/app/docs/controller/settings/SettingsSession.js, src/app/docs/controller/settings/SettingsUser.js, src/app/docs/controller/settings/SettingsUserEdit.js, src/app/docs/controller/settings/SettingsVocabulary.js, src/app/docs/controller/tag/Tag.js, src/app/docs/controller/usergroup/GroupProfile.js, src/app/docs/controller/usergroup/UserGroup.js, src/app/docs/controller/usergroup/UserProfile.js, src/app/docs/directive/Acl.js, src/app/docs/directive/AuditLog.js, src/app/docs/directive/File.js, src/app/docs/directive/ImgError.js, src/app/docs/directive/InlineEdit.js, src/app/docs/directive/SelectRelation.js, src/app/docs/directive/SelectTag.js, src/app/docs/filter/Filesize.js, src/app/docs/filter/Newline.js, src/app/docs/filter/Shorten.js, src/app/docs/service/Tag.js, src/app/docs/service/User.js, src/app/share/app.js, src/app/share/controller/FileModalView.js, src/app/share/controller/FileView.js, src/app/share/controller/Main.js, src/app/share/controller/Share.js, src/app/share/controller/ShareModalPdf.js, src/app/share/filter/Filesize.js, src/app/share/filter/Newline.js
[exec]
[exec] Running "concat:docs" (concat) task
[exec] File "dist/docs.js" created.
[exec]
[exec] Running "concat:share" (concat) task
[exec] File "dist/share.js" created.
[exec]
[exec] Running "less:dist" (less) task
[exec] File dist/less.css created.
[exec]
[exec] Running "concat:css" (concat) task
[exec] File "dist/style.css" created.
[exec]
[exec] Running "cssmin:dist" (cssmin) task
[exec] File 'dist/style/style.min.css' written.
[exec] Uncompressed size: 165398 bytes.
[exec] Compressed size: 31032 bytes gzipped (139383 bytes minified).
[exec]
[exec] Running "uglify:docs" (uglify) task
[exec] File dist/docs.min.js created.
[exec]
[exec] Running "uglify:share" (uglify) task
[exec] File dist/share.min.js created.
[exec]
[exec] Running "copy:dist" (copy) task
[exec] Created 23 directories, copied 53 files
[exec]
[exec] Running "remove:dist" (remove) task
[exec]
[exec] Running "cleanempty:src" (cleanempty) task
[exec] Cleaning dist/locale...OK
[exec] Cleaning dist/lib...OK
[exec]
[exec] Running "htmlrefs:index" (htmlrefs) task
[exec]
[exec] Running "htmlrefs:share" (htmlrefs) task
[exec]
[exec] Running "replace:dist" (replace) task
[exec]
[exec] Done, without errors.
...
Quelle: run npm command gives error „/usr/bin/env: node: No such file or directory“
.war kompilieren
Nun ist alles da, um das .war zu kompilieren:
# cd /usr/local/bin/sismics/docs-web
# mvn -Pprod -DskipTests clean install
...
[INFO] Installing /usr/local/bin/sismics/docs-web/target/docs-web-1.0-SNAPSHOT.war to /root/.m2/repository/com/sismics/docs/docs-web/1.0-SNAPSHOT/docs-web-1.0-SNAPSHOT.war
[INFO] Installing /usr/local/bin/sismics/docs-web/pom.xml to /root/.m2/repository/com/sismics/docs/docs-web/1.0-SNAPSHOT/docs-web-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14.935 s
[INFO] Finished at: 2016-03-27T10:37:55+00:00
[INFO] Final Memory: 28M/68M
[INFO] ------------------------------------------------------------------------
Jetty installieren und das .war bekanntmachen
Als nächstes installiert man Jetty:
# apt-get install jetty9
Sobald Jetty existiert, kopiert man das vorhin kompilierte .war in folgendes Verzeichnis:
# cp /root/.m2/repository/com/sismics/docs/docs-web/1.0-SNAPSHOT/docs-web-1.0-SNAPSHOT.war /usr/share/jetty9/webapps/dms.war
ACHTUNG: Es gibt auch ein Verzeichnis /usr/share/jetty/webapps/; Jetty ignoriert dieses aber (meiner Meinung nach). Das .war gehört nicht hierhin.
Datenverzeichnis anlegen
# mkdir /var/docs
# chmod 777 /var/docs
Jetty neu starten
# service jetty9 start
Sismics Docs aufrufen
Sobald Jetty läuft, öffnet man den Browser wieder:
10.1.2.3:8080/dms/
Man loggt sich ein, ändert das Admin-Passwort, erstellt weitere User, lädt ein Testdokument hoch, loggt sich wieder aus — und dann stoppt man Jetty testhalber wieder um sicherzugehen, dass die Daten und Konfiguration auch einen Stop des Applikationsservers überlegen:
# service jetty9 stop
# service jetty9 start
Nun sollte man sich mit dem soeben gesetzten Admin-Passwort einloggen können und das vorher hochgeladene Dokument sehen.
Fertig! Nun kann der Spass beginnen.
Die API-Dokumentation habe ich leider noch nicht gefunden …