8.7 Installationsanleitung

Einleitung

Die folgende Installationsanleitung für den Goobi viewer bezieht sich auf Ubuntu Linux 16.04. Sie ist als Schritt für Schritt Anleitung von oben nach unten geschrieben, das bedeutet, dass Einstellungen und Konfigurationen aufeinander aufbauen. Wird die Reihenfolge nicht eingehalten, können unter Umständen bestimmte Befehle fehlschlagen.‌

Als Domainname wird in dieser Anleitung VIEWER.EXAMPLE.ORG verwendet und muss an den eigenen DNS Namen angepasst werden.‌

Vorbereitung

‌Zuerst auf dem Server auf dem der Goobi viewer installiert werden soll anmelden und root Rechte erlangen:

ssh VIEWER.EXAMPLE.ORG
sudo -i

‌Anschließend ein Passwort für die Goobi viewer Datenbank und einen Token generieren und als Variable in der Session ablegen. Dort wird ebenfalls der DNS Name hinterlegt:

export PW_SQL_VIEWER=SECRETPASSWORT
export TOKEN=$(uuidgen)
export VIEWER_HOSTNAME=VIEWER.EXAMPLE.ORG

‌Nun die folgenden Pakete installieren:

apt -y install git maven

Zum Schluss der Vorbereitung muss ein temporäres Verzeichnis für die Installation angelegt und das Goobi viewer Connector, Goobi viewer Indexer und Goobi viewer Core Config Repository geklont werden. Darin sind für die Installation notwendige Dateien enthalten:

install=/tmp/install
mkdir -p $install
cd $install
git clone https://github.com/intranda/goobi-viewer-connector.git
git clone https://github.com/intranda/goobi-viewer-indexer.git
git clone https://github.com/intranda/goobi-viewer-core-config.git

‌Es empfiehlt sich zum jetzigen Zeitpunkt einen DNS Eintrag für den Server gesetzt zu haben.

Variablen und Aliase

‌Folgende Aliase in die /root/.bash_aliases hinzufügen:

cat << "EOF" >/root/.bash_aliases
alias cata='tail -n 1000 -f /var/log/tomcat8/catalina.out'
alias ct='chown tomcat8:tomcat8 *'
alias ctr='chown -R tomcat8:tomcat8 *'
alias ind='tail -n 1000 -f /opt/digiverso/logs/indexer.log'
alias vl='tail -n 1000 -f /opt/digiverso/logs/viewer.log'
EOF

‌Übernahme der Änderungen in der aktuellen Session:

. /root/.bashrc

Pakete installieren

‌Folgenden Pakete inklusive aller Abhängigkeiten installieren:

apt -y install openjdk-8-jdk-headless tomcat8 mariadb-server apache2 ttf-mscorefonts-installer unzip

Services konfigurieren

Tomcat

In der /etc/default/tomcat8 den Speicher unter -Xmx dem verfügbaren Maschinenspeicher angepassen, vernünftige Garbage Collector Optionen wählen und urandom für schnelleren Tomcat start nutzen:

patch /etc/default/tomcat8 << "EOF"
--- /etc/default/tomcat8 2018-03-01 19:11:46.947240791 +0000
+++ tomcat8 2018-03-01 19:14:01.920680439 +0000
@@ -18,7 +18,13 @@
# response time). If you use that option and you run Tomcat on a machine with
# exactly one CPU chip that contains one or two cores, you should also add
# the "-XX:+CMSIncrementalMode" option.
-JAVA_OPTS="-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC"
+JAVA_OPTS="-Djava.awt.headless=true -Xmx4g -Xms2g"
+JAVA_OPTS="${JAVA_OPTS} -XX:+UseG1GC"
+JAVA_OPTS="${JAVA_OPTS} -XX:+ParallelRefProcEnabled"
+JAVA_OPTS="${JAVA_OPTS} -XX:+DisableExplicitGC"
+JAVA_OPTS="${JAVA_OPTS} -XX:+CMSClassUnloadingEnabled"
+JAVA_OPTS="${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom"
+JAVA_OPTS="${JAVA_OPTS} -Dfile.encoding='utf-8'"
# To enable remote debugging uncomment the following line.
# You will then be able to use a java debugger on port 8000.
@@ -32,9 +39,9 @@
#TOMCAT8_SECURITY=no
# Number of days to keep logfiles in /var/log/tomcat8. Default is 14 days.
-#LOGFILE_DAYS=14
+LOGFILE_DAYS=14
# Whether to compress logfiles older than today's
-#LOGFILE_COMPRESS=1
+LOGFILE_COMPRESS=1
# Location of the JVM temporary directory
# WARNING: This directory will be destroyed and recreated at every startup !
EOF

Weitere Konfigurationen werden in /etc/tomcat8/server.xml vorgenommen. Dabei werden die appContextProtection für den JreMemoryLeakPreventionListener ausgeschaltet, sowie einen HTTP connector (mit korrektem proxyName) und einen AJP Connector auf localhost eingerichtet. Weiter wird ein Crawler Session Manager Valve aktiviert:

sed -e "s|VIEWER.EXAMPLE.ORG|${VIEWER_HOSTNAME}|g" << "EOF" | patch /etc/tomcat8/server.xml
--- /etc/tomcat8/server.xml 2017-09-28 14:56:31.000000000 +0100
+++ server.xml 2018-03-01 19:18:50.143658964 +0000
@@ -29,7 +29,7 @@
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
-->
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
- <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
+ <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" appContextProtection="false" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
@@ -68,33 +68,18 @@
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
- <Connector port="8080" protocol="HTTP/1.1"
- connectionTimeout="20000"
- URIEncoding="UTF-8"
- redirectPort="8443" />
- <!-- A "Connector" using the shared thread pool-->
- <!--
- <Connector executor="tomcatThreadPool"
- port="8080" protocol="HTTP/1.1"
- connectionTimeout="20000"
- redirectPort="8443" />
- -->
- <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443
- This connector uses the NIO implementation that requires the JSSE
- style configuration. When using the APR/native implementation, the
- OpenSSL style configuration is required as described in the APR/native
- documentation -->
- <!--
- <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
- maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
- clientAuth="false" sslProtocol="TLS" />
- -->
-
- <!-- Define an AJP 1.3 Connector on port 8009 -->
- <!--
- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
- -->
-
+<Connector address="127.0.0.1" port="8080" protocol="HTTP/1.1"
+ connectionTimeout="20000"
+ maxThreads="400"
+ URIEncoding="UTF-8"
+ enableLookups="false"
+ disableUploadTimeout="true"
+ proxyName="VIEWER.EXAMPLE.ORG"
+ proxyPort="80" />
+
+<Connector address="127.0.0.1" port="8009" protocol="AJP/1.3"
+ URIEncoding="UTF-8"
+ redirectPort="8443" />
<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
@@ -137,10 +122,12 @@
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
- <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
+ <!--Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
- pattern="%h %l %u %t &quot;%r&quot; %s %b" />
-
+ pattern="%h %l %u %t &quot;%r&quot; %s %b" /-->
+ <Valve className="org.apache.catalina.valves.CrawlerSessionManagerValve"
+ crawlerUserAgents=".*[bB]ot.*|.*Yahoo! Slurp.*|.*Feedfetcher-Google.*|.*Apache-HttpClient.*|.*[Ss]pider.*|.*[Cc]rawler.*|.*nagios.*|.*Yandex.*"
+ sessionInactiveInterval="60"/>
</Host>
</Engine>
</Service>
EOF

Die Sessionpersistenz in der /​etc/​tomcat8/​context.xml deaktivieren,​ indem der folgende Patch ausgeführt wird.

patch /etc/tomcat8/context.xml << "EOF"
--- /etc/tomcat8/context.xml 2014-01-24 17:17:30.000000000 +0000
+++ context.xml 2018-03-01 19:23:05.166223891 +0000
@@ -24,9 +24,7 @@
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
- <!--
<Manager pathname="" />
- -->
<!-- Uncomment this to enable Comet connection tacking (provides events
on session expiration as well as webapp lifecycle) -->
EOF

Apache

Apache muss eingerichtet werden, um den Viewer extern zur Verfügung zu stellen. Dafür die folgenden Module aktivieren:

a2enmod proxy_ajp
a2enmod rewrite
a2enmod expires
a2enmod headers

Die folgende Datei nach /etc/apache2/sites-available/${VIEWER_HOSTNAME}.conf legen:

sed -e "s|VIEWER.EXAMPLE.ORG|${VIEWER_HOSTNAME}|g" << "EOF" >/etc/apache2/sites-available/${VIEWER_HOSTNAME}.conf
<VirtualHost *:80>
ServerAdmin support@intranda.com
ServerName VIEWER.EXAMPLE.ORG
DocumentRoot /var/www
## make sure rewrite is enabled
RewriteEngine On
## search engines: do not follow certain urls
RewriteCond %{HTTP_USER_AGENT} ^.*bot.*$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*Yandex.*$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*spider.*$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*rawler.*$ [NC]
ReWriteRule ^(.*);jsessionid=[A-Za-z0-9]+(.*)$ $1$2 [L,R=301]
RewriteCond %{HTTP_USER_AGENT} ^.*bot.*$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*Yandex.*$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*spider.*$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*rawler.*$ [NC]
ReWriteRule ^(.*)viewer/!(.*)$ $1viewer/$2 [L,R=301]
RewriteCond %{HTTP_USER_AGENT} ^.*bot.*$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*Yandex.*$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*spider.*$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*rawler.*$ [NC]
ReWriteRule ^(.*)/[Ll][Oo][Gg]_(.*)$ $1/ [L,R=301]
## compress output
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain text/html text/xml
AddOutputFilterByType DEFLATE text/css text/javascript
AddOutputFilterByType DEFLATE application/xml application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript application/x-javascript
</IfModule>
## general proxy settings
ProxyPreserveHost On
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
<Proxy *>
Require local
</Proxy>
## CORS for IIIF
Header set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "GET, OPTIONS"
Header always set Access-Control-Max-Age "600"
Header always set Access-Control-Allow-Headers "Authorization, Content-Type"
Header always set Access-Control-Expose-Headers "Content-Security-Policy, Location"
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
# make sure ETag headers are forwarded correctly
# Post Apache 2.4 have a look at
# https://httpd.apache.org/docs/trunk/mod/mod_deflate.html#deflatealteretag
RequestHeader edit "If-None-Match" '(.*)-gzip"$' '$1", $1-gzip"'
## Viewer
redirect 301 /index.html http://VIEWER.EXAMPLE.ORG/viewer/
redirect 301 /viewer http://VIEWER.EXAMPLE.ORG/viewer/
RewriteRule ^/viewer/oai/oai2.xsl$ http://VIEWER.EXAMPLE.ORG/viewer/oai2.xsl
ProxyPassMatch ^/viewer/(oai.*)$ ajp://localhost:8009/M2M/$1 retry=0
<LocationMatch ^/viewer/(oai.*)$>
Forcetype text/xml
ProxyPassReverse ajp://localhost:8009/M2M/$1
</LocationMatch>
ProxyPassMatch ^/viewer/(sru.*)$ ajp://localhost:8009/M2M/$1 retry=0
<LocationMatch ^/viewer/(sru.*)$>
Forcetype text/xml
ProxyPassReverse ajp://localhost:8009/M2M/$1
</LocationMatch>
ProxyPassMatch ^/viewer/(.*)$ ajp://localhost:8009/viewer/$1 retry=0
<LocationMatch ^/viewer/(.*)$>
ProxyPassReverse ajp://localhost:8009/viewer/$1
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType image/jpg "access plus 1 months"
ExpiresByType image/gif "access plus 1 months"
ExpiresByType image/jpeg "access plus 1 months"
ExpiresByType image/png "access plus 1 months"
ExpiresByType font/ttf "access plus 1 year"
ExpiresByType application/x-font-woff "access plus 1 year"
ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
</IfModule>
Require all granted
</LocationMatch>
## solr
redirect 301 /solr http://VIEWER.EXAMPLE.ORG/solr/
<Location /solr/>
Require local
ProxyPass ajp://localhost:8009/solr/ retry=0
ProxyPassReverse ajp://localhost:8009/solr/
</Location>
## logging
CustomLog /var/log/apache2/VIEWER.EXAMPLE.ORG_access.log combined
ErrorLog /var/log/apache2/VIEWER.EXAMPLE.ORG_error.log
# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel warn
</VirtualHost>
EOF

Den Goobi viewer vhost aktivieren, den default vhost deaktivieren und den Apache Webserver neu starten:

a2dissite 000-default
a2ensite ${VIEWER_HOSTNAME}.conf
systemctl restart apache2.service

Zum Schluss noch eine robots.txt anlegen:

sed -e "s|VIEWER.EXAMPLE.ORG|${VIEWER_HOSTNAME}|g" << "EOF" >/var/www/robots.txt
User-agent: *
Disallow: /viewer/content*action=pdf
Disallow: /viewer/search/
Disallow: /viewer/tags/
Disallow: /viewer/term/
Disallow: /viewer/oai
Disallow: /viewer/nextHit/
Disallow: /viewer/prevHit/
#Sitemap: http://VIEWER.EXAMPLE.ORG/viewer/sitemap_index.xml
Crawl-delay: 10
EOF

MySQL / MariaDB

‌Goobi viewer benötigt eine Datenbank und einen eigenen Nutzer. Dies wird mit dem folgenden Befehl angelegt:

mysql -e "CREATE DATABASE viewer;
CREATE USER 'viewer'@'localhost' IDENTIFIED BY '$PW_SQL_VIEWER';
GRANT ALL PRIVILEGES ON viewer.* TO 'viewer'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;"

Das Datenbankschema wird beim ersten Start der Applikation automatisch erstellt.

NFS

Dieser Punkt ist nur relevant, wenn Goobi workflow ebenfalls installiert ist/wird, und das nicht auf der gleichen Maschine erfolgt.

Dann muss der Ordner /opt/digiverso/viewer zu dem Goobi workflow Server exportiert werden. Hierfür wird NFS genutzt. Die Anpassungen dafür sind hier:

export IP_GOOBI=1.2.3.4 # IP-Adresse des Goobi workflow Servers
apt install nfs-kernel-server -y
echo "/opt/digiverso/viewer/hotfolder ${IP_GOOBI}/255.255.255.255(rw,sync,no_subtree_check,all_squash,anonuid=$(id -u tomcat8),anongid=$(id -g tomcat8))" >> /etc/exports
systemctl restart nfs-kernel-server.service

Der Port für NFSv4 ist TCP 2049, falls UFW benutzt wird:

ufw allow from $IP_GOOBI proto tcp to any port 2049

Die Anpassungen für Goobi workflow können in der dortigen Installationsanleitung nachgelesen werden:

Verzeichnisstruktur erstellen

Mit den folgenden Befehlen wird die notwendige Ordnerstruktur erzeugt und die Dateien aus dem Repository an die erwartete Stelle verschoben:

mkdir -p /opt/digiverso/{config/bin,indexer,logs,tomcat-lib,viewer/{abbyy,cmdi,deleted_mets,hotfolder,media,orig_lido,orig_denkxweb,success,ugc,alto,cms_media,error_mets,indexed_lido,mix,pdf,tei,updated_mets,cache,config/{PDFTitlePage,watermark},fulltext,indexed_mets,oai/token,ptif,themes,wc,bin}}
chown -R tomcat8: /opt/digiverso

Installation

Im folgenden ist die Installation der benötigten Komponenten beschrieben.

Apache Solr

Die aktuelle Solr 4.x Version herunterladen und entpacken:

wget -O $install/solr.tgz http://archive.apache.org/dist/lucene/solr/4.10.4/solr-4.10.4.tgz
tar -C $install -xzf $install/solr.tgz

Den Ordner example/solr nach /opt/digiverso/viewer/apache-solr verschieben:

mkdir -p /opt/digiverso/viewer/apache-solr/
mv $install/solr-4.10.4/example/solr/* /opt/digiverso/viewer/apache-solr/

In der solr.xml den gesamten Block solrCloud auskommentieren und einen Core konfigurieren:

patch /opt/digiverso/viewer/apache-solr/solr.xml << "EOF"
--- /opt/digiverso/viewer/apache-solr/solr.xml 2014-09-08 09:56:09.000000000 +0200
+++ /tmp/solr.xml 2018-04-17 17:11:08.624242625 +0200
@@ -26,17 +26,13 @@
http://wiki.apache.org/solr/CoreAdmin
-->
<solr>
- <solrcloud>
- <str name="host">${host:}</str>
- <int name="hostPort">${jetty.port:8983}</int>
- <str name="hostContext">${hostContext:solr}</str>
- <int name="zkClientTimeout">${zkClientTimeout:30000}</int>
- <bool name="genericCoreNodeNames">${genericCoreNodeNames:true}</bool>
- </solrcloud>
+ <cores adminPath="/admin/cores" defaultCoreName="collection1">
+ <core name="collection1" instanceDir="collection1" />
+ </cores>
<shardHandlerFactory name="shardHandlerFactory"
class="HttpShardHandlerFactory">
<int name="socketTimeout">${socketTimeout:0}</int>
<int name="connTimeout">${connTimeout:0}</int>
EOF

Verschieben der benötigten Libraries:

mkdir -p /opt/digiverso/viewer/apache-solr/lib
mv -t /opt/digiverso/viewer/apache-solr/lib $install/solr-4.10.4/contrib/analysis-extras/lucene-libs/lucene-analyzers-icu-4.10.4.jar $install/solr-4.10.4/contrib/analysis-extras/lib/icu4j-53.1.jar $install/solr-4.10.4/dist/solr-analysis-extras-4.10.4.jar

Übernahme der solr.war:

mv $install/solr-4.10.4/dist/solr-4.10.4.war /opt/digiverso/viewer/apache-solr/solr.war

Anpassen der collection1/conf/solrconfig.xml:

patch /opt/digiverso/viewer/apache-solr/collection1/conf/solrconfig.xml << "EOF"
--- /opt/digiverso/viewer/apache-solr/collection1/conf/solrconfig.xml 2015-02-27 19:09:58.000000000 +0100
+++ /tmp/solrconfig.xml 2018-04-17 17:21:23.353907791 +0200
@@ -70,19 +70,9 @@
is found that matches, a warning will be logged.
The examples below can be used to load some solr-contribs along
with their external dependencies.
-->
- <lib dir="${solr.install.dir:../../..}/contrib/extraction/lib" regex=".*\.jar" />
- <lib dir="${solr.install.dir:../../..}/dist/" regex="solr-cell-\d.*\.jar" />
-
- <lib dir="${solr.install.dir:../../..}/contrib/clustering/lib/" regex=".*\.jar" />
- <lib dir="${solr.install.dir:../../..}/dist/" regex="solr-clustering-\d.*\.jar" />
-
- <lib dir="${solr.install.dir:../../..}/contrib/langid/lib/" regex=".*\.jar" />
- <lib dir="${solr.install.dir:../../..}/dist/" regex="solr-langid-\d.*\.jar" />
-
- <lib dir="${solr.install.dir:../../..}/contrib/velocity/lib" regex=".*\.jar" />
- <lib dir="${solr.install.dir:../../..}/dist/" regex="solr-velocity-\d.*\.jar" />
+ <lib dir="../lib" />
<!-- an exact 'path' can be used instead of a 'dir' to specify a
specific jar file. This will cause a serious error to be logged
@@ -97,11 +87,11 @@
Used to specify an alternate directory to hold all index data
other than the default ./data under the Solr home. If
replication is in use, this should match the replication
configuration.
-->
- <dataDir>${solr.data.dir:}</dataDir>
+ <dataDir>${solr.data.dir:/opt/digiverso/viewer/apache-solr/collection1/data}</dataDir>
<!-- The DirectoryFactory to use for indexes.
solr.StandardDirectoryFactory is filesystem
@@ -838,11 +828,11 @@
will be overridden by parameters in the request
-->
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
- <str name="df">text</str>
+ <str name="df">DEFAULT</str>
</lst>
<!-- In addition to defaults, "appends" params can be specified
to identify values which should be appended to the list of
multi-val params from the query (or the existing "defaults").
-->
@@ -900,11 +890,11 @@
<requestHandler name="/query" class="solr.SearchHandler">
<lst name="defaults">
<str name="echoParams">explicit</str>
<str name="wt">json</str>
<str name="indent">true</str>
- <str name="df">text</str>
+ <str name="df">DEFAULT</str>
</lst>
</requestHandler>
<!-- realtime get handler, guaranteed to return the latest stored fields of
@@ -971,11 +961,11 @@
<str name="defType">edismax</str>
<str name="qf">
text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4
title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0
</str>
- <str name="df">text</str>
+ <str name="df">DEFAULT</str>
<str name="mm">100%</str>
<str name="q.alt">*:*</str>
<str name="rows">10</str>
<str name="fl">*,score</str>
@@ -1403,11 +1393,11 @@
See http://wiki.apache.org/solr/SpellCheckComponent for details
on the request parameters.
-->
<requestHandler name="/spell" class="solr.SearchHandler" startup="lazy">
<lst name="defaults">
- <str name="df">text</str>
+ <str name="df">DEFAULT</str>
<!-- Solr will use suggestions from both the 'default' spellchecker
and from the 'wordbreak' spellchecker and combine them.
collations (re-written queries) can include a combination of
corrections from both spellcheckers -->
<str name="spellcheck.dictionary">default</str>
@@ -1463,11 +1453,11 @@
In reality you will likely want to add the component to your
already specified request handlers.
-->
<requestHandler name="/tvrh" class="solr.SearchHandler" startup="lazy">
<lst name="defaults">
- <str name="df">text</str>
+ <str name="df">DEFAULT</str>
<bool name="tv">true</bool>
</lst>
<arr name="last-components">
<str>tvComponent</str>
</arr>
@@ -1609,11 +1599,11 @@
<!-- A request handler for demonstrating the elevator component -->
<requestHandler name="/elevate" class="solr.SearchHandler" startup="lazy">
<lst name="defaults">
<str name="echoParams">explicit</str>
- <str name="df">text</str>
+ <str name="df">DEFAULT</str>
</lst>
<arr name="last-components">
<str>elevator</str>
</arr>
</requestHandler>
EOF

Übernahme des Solr Schemas und der Mappingdatei für diakritische Zeichen aus dem Goobi viewer Indexer Repository:

mv $install/goobi-viewer-indexer/goobi-viewer-indexer/src/main/resources/other/schema.xml /opt/digiverso/viewer/apache-solr/collection1/conf/
mv $install/goobi-viewer-indexer/goobi-viewer-indexer/src/main/resources/other/mapping-ISOLatin1Accent.txt /opt/digiverso/viewer/apache-solr/collection1/conf/

Verlinkung der stopwords Datei:

ln --relative -s /opt/digiverso/viewer/apache-solr/collection1/conf/lang/stopwords_de.txt /opt/digiverso/viewer/apache-solr/collection1/conf/lang/stopwords.txt

Konfiguration des Loggings (siehe auch hier):

mkdir /opt/digiverso/viewer/apache-solr/tomcat-lib/
mv $install/solr-4.10.4/example/lib/ext/*.jar /opt/digiverso/viewer/apache-solr/tomcat-lib/

Solr in Tomcat bekannt machen:

cat << "EOF" >/etc/tomcat8/Catalina/localhost/solr.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="/opt/digiverso/viewer/apache-solr/solr.war" crossContext="true">
<Environment name="solr/home" type="java.lang.String" value="/opt/digiverso/viewer/apache-solr" override="true"/>
<Resources>
<PreResources
className="org.apache.catalina.webresources.DirResourceSet"
base="/opt/digiverso/viewer/apache-solr/tomcat-lib/"
webAppMount="/WEB-INF/lib" />
</Resources>
</Context>
EOF

Zum Schluß noch ein Verzeichnis für die Daten erstellen und die Rechte anpassen:

mkdir /opt/digiverso/viewer/apache-solr/collection1/data/
chown -R tomcat8: /opt/digiverso/viewer/apache-solr

Für die Indexierung und Suche nach Koordinaten wird noch eine weitere Java Library benötigt, die in dem entpackten WEB-INF/lib/ Ordner von Solr kopiert werden muss:

wget -O /tmp/jts-1.14.zip http://downloads.sourceforge.net/project/jts-topo-suite/jts/1.14/jts-1.14.zip
unzip -j /tmp/jts-1.14.zip "lib/jts-1.14.jar" -d /tmp
mv /tmp/jts-1.14.jar /var/lib/tomcat8/webapps/solr/WEB-INF/lib/

Goobi viewer Indexer

Zuerst wird die Applikation kompiliert. Danach werden die benötigten Dateien nach /opt/digiverso/indexer/ kopiert und dabei die indexerconfig_solr.xml nach solr_indexerconfig.xml umbenannt, der Tomcat Port kontrolliert und gegebenenfalls C: durch /opt ersetze. Zum Schluss wird die systemd Service Unit aktiviert:

mvn -f $install/goobi-viewer-indexer/goobi-viewer-indexer package
mv -t /opt/digiverso/indexer/solrIndexer.jar $install/goobi-viewer-indexer/goobi-viewer-indexer/target/solr-Indexer.jar
sed -e 's/8081/8080/g' -e 's/C:/\/opt/g' $install/goobi-viewer-indexer/goobi-viewer-indexer/target/classes/indexerconfig_solr.xml -e 's/collection2/collection1/g' > /opt/digiverso/indexer/solr_indexerconfig.xml
mv $install/goobi-viewer-indexer/goobi-viewer-indexer/src/main/resources/other/solrindexer.service /etc/systemd/system/
systemctl enable solrindexer.service

Goobi viewer

Den Tomcat Dienst stoppen:

systemctl stop tomcat8

‌Danach die folgende Datei nach /etc/tomcat8/Catalina/localhost/viewer.xml legen:

sed -e "s|PW_SQL_VIEWER|${PW_SQL_VIEWER}|g" << "EOF" >/etc/tomcat8/Catalina/localhost/viewer.xml
<?xml version='1.0' encoding='UTF-8'?>
<Context>
<Resources>
<PreResources
className="org.apache.catalina.webresources.DirResourceSet"
base="/opt/digiverso/tomcat-lib/"
webAppMount="/WEB-INF/lib" />
<PreResources
className="org.apache.catalina.webresources.DirResourceSet"
base="/opt/digiverso/viewer/themes/goobi-viewer-theme-reference/goobi-viewer-theme-reference/WebContent/resources/themes/"
webAppMount="/resources/themes" />
</Resources>
<Resource
name="viewer"
auth="Container"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
type="javax.sql.DataSource"
driverClassName="org.mariadb.jdbc.Driver"
username="viewer"
password="PW_SQL_VIEWER"
maxActive="100"
maxIdle="30"
minIdle="4"
maxWait="10000"
testOnBorrow="true"
testWhileIdle="true"
validationQuery="SELECT SQL_NO_CACHE 1"
removeAbandoned="true"
removeAbandonedTimeout="600"
url="jdbc:mysql://localhost/viewer?characterEncoding=UTF-8&amp;autoReconnect=true&amp;autoReconnectForPools=true" />
</Context>
EOF

Nun die Dateirechte anpassen, damit die Datei bei einem Update nicht mit gelöscht wird:

chown -R root.tomcat8 /etc/tomcat8/Catalina
chmod -R g-w /etc/tomcat8/Catalina

Das Theme wird als externes Theme eingebunden:

mkdir -p /opt/digiverso/viewer/themes/
cd /opt/digiverso/viewer/themes/
git clone https://github.com/intranda/goobi-viewer-theme-reference.git

Nun den Goobi viewer kompilieren und an die erwartete Stelle im Dateisystem verschieben:

mvn -f /opt/digiverso/viewer/themes/goobi-viewer-theme-reference/goobi-viewer-theme-reference package
mv /opt/digiverso/viewer/themes/goobi-viewer-theme-reference/goobi-viewer-theme-reference/target/viewer.war /var/lib/tomcat8/webapps/viewer.war

Zum Schluss noch letzte Konfigurationsdateien verschieben und danach den Tomcat Dienst wieder starten:

mv $install/goobi-viewer-core-config/goobi-viewer-core-config/src/main/resources/install/* /opt/digiverso/viewer/config/
chown -R tomcat8: /opt/digiverso/viewer/
systemctl start tomcat8

Connector - (OAI & SRU)

Für die Installation der OAI und SRU Schnittstelle muss zuerst die Applikation kompiliert werden:

mvn -f $install/goobi-viewer-connector/goobi-viewer-connector package

Danach müssen die war-Datei und die Konfigurationsdateien an die erwartete Stelle verschoben werden:

mv $install/goobi-viewer-connector/goobi-viewer-connector/target/M2M.war /opt/digiverso/viewer/bin/M2M.war
mv $install/goobi-viewer-connector/goobi-viewer-connector/target/M2M/WEB-INF/classes/*.xsl /opt/digiverso/viewer/oai/
chown -R tomcat8: /opt/digiverso/viewer/bin/
chown -R tomcat8: /opt/digiverso/viewer/oai/

Danach die folgende Datei nach /etc/tomcat8/Catalina/localhost/M2M.xml legen:

cat << "EOF" >/etc/tomcat8/Catalina/localhost/M2M.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/M2M"
docBase="/opt/digiverso/viewer/bin/M2M.war"
crossContext="true"
reloadable="true">
</Context>
EOF

Extraktion der config_oai.xml:

unzip -p /opt/digiverso/viewer/bin/M2M.war WEB-INF/classes/config_oai.xml > /opt/digiverso/viewer/config/config_oai.xml

Anpassen der Einstellungen auf die korrekte URL, damit die Resolver-Links funktionieren und sicherstellen, dass der Port des Tomcats auf dem der Solr Dienst läuft 8080 entspricht:

sed -i -e "s|http://localhost:8080/viewer/oai|http://${VIEWER_HOSTNAME}/viewer/oai|g" -e "s|http://localhost:8080/viewer/resolver|http://${VIEWER_HOSTNAME}/viewer/resolver|g" -e "s|http://localhost:8080/viewer/piresolver|http://${VIEWER_HOSTNAME}/viewer/piresolver|g" -e "s|http://localhost:8081/solr|http://localhost:8080/solr|g" /opt/digiverso/viewer/config/config_oai.xml

Einstellungen

Cronjob

Für regelmäßige Aufgaben muss ein Cronjob eingerichtet werden:

sed -e "s|VIEWER.EXAMPLE.ORG|${VIEWER_HOSTNAME}|g" -e "s|TOKEN|${TOKEN}|g" << "EOF" >/etc/cron.d/intranda-goobiviewer
PATH=/usr/bin:/bin:/usr/sbin/
MAILTO=admin@intranda.com
#
# Regular cron jobs for the Goobi viewer
#
## This REST call triggers the email notification about new search hits for users,
## that enabled notifications for saved searches
42 8,12,17 * * * root curl -s http://localhost:8080/viewer/rest/search/sendnotifications/?token=TOKEN
## This REST call creates an XML sitemap for the Goobi viewer instance. Please always
## call it on it's external URL because otherwise the protocol (http/https) might not
## be detected correctly
18 1 * * * root curl -s -X POST -H "Content-Type: application/json" -d '{}' "http://VIEWER.EXAMPLE.ORG/viewer/rest/sitemap/update/?token=TOKEN" 1>/dev/null
## These two scripts pull the theme git repository regulary. The @daily part is only
## a reminder for the 1-minute schedule
#*/1 * * * * root cd /opt/digiverso/viewer/themes/goobi-viewer-theme-reference; git pull | grep -v -e "Already up.to.date." -e "Bereits aktuell."
#@daily root echo "Please look at the git checkout interval for the Goobi viewer theme" | mail -s "Reference: Theme repository is checked out every minute" admin@intranda.com
## Optimize the Solr search index once a month
@monthly root curl -s http://localhost:8080/solr/update?optimize=true&waitFlush=false
EOF

config_viewer.xml

In der lokalen config_viewer.xml müssen verschiedene Einstellungen hinterlegt werden, hierbei müssen Domain und gegebenenfalls das Protokoll angepasst werden:

sed -e "s|VIEWER.EXAMPLE.ORG|${VIEWER_HOSTNAME}/viewer|g" -e "s|TOKEN|${TOKEN}|g" << "EOF" >/opt/digiverso/viewer/config/config_viewer.xml
<?xml version="1.0" encoding="UTF-8" ?>
<config>
<urls>
<metadata>
<mets>http://VIEWER.EXAMPLE.ORG/oai?verb=GetRecord&amp;metadataPrefix=mets&amp;identifier=</mets>
<marc>http://VIEWER.EXAMPLE.ORG/oai?verb=GetRecord&amp;metadataPrefix=marcxml&amp;identifier=</marc>
<dc>http://VIEWER.EXAMPLE.ORG/oai?verb=GetRecord&amp;metadataPrefix=oai_dc&amp;identifier=</dc>
<ese>http://VIEWER.EXAMPLE.ORG/oai?verb=GetRecord&amp;metadataPrefix=europeana&amp;identifier=</ese>
</metadata>
<contentServerWrapper>http://VIEWER.EXAMPLE.ORG/content/</contentServerWrapper>
<download>http://VIEWER.EXAMPLE.ORG/download/</download>
<rest>http://VIEWER.EXAMPLE.ORG/rest/</rest>
</urls>
<viewer>
<theme subTheme="false" mainTheme="reference" discriminatorField="" autoSwitch="true" addFilterQuery="false" filterQueryVisible="false">
<rootPath>/opt/digiverso/goobi-viewer-theme-reference/goobi-viewer-theme-reference/WebContent/resources/themes/</rootPath>
</theme>
</viewer>
<rss>
<numberOfItems>50</numberOfItems>
<title>Goobi viewer RSS Feed</title>
<description>new items</description>
<copyright>(c) Goobi viewer using institution </copyright>
</rss>
<webapi>
<authorization>
<token>TOKEN</token>
</authorization>
</webapi>
</config>
EOF

Benutzeraccount anlegen

Der Goobi viewer verfügt über ein Backend. Mit dem folgenden Kommando wird ein Testaccount mit dem Benutzernamen goobi@intranda.com und dem Passwort viewer in die Datenbank eingefügt:

mysql -e 'USE viewer;
INSERT INTO users (active,email,password_hash,score,superuser) VALUES (1,"goobi@intranda.com","$2a$10$Z5GTNKND9ZbuHt0ayDh0Remblc7pKUNlqbcoCxaNgKza05fLtkuYO",0,1);'