Add installation script + Dockerfile for OpenDataKit, closes #67

This commit is contained in:
Disassembler 2018-03-16 16:08:18 +01:00
parent 8a0abe9c99
commit 77043ccd62
Signed by: Disassembler
GPG Key ID: 524BD33A0EE29499
12 changed files with 335 additions and 1 deletions

View File

@ -71,6 +71,7 @@ vi 00-install.sh
| MariaDB | 3306 (MySQL) | N/A | N/A |
| Mifos X | 8012 (HTTP) | 8812 | 8412 |
| Motech | 8013 (HTTP) | 8813 | 8413 |
| OpenDataKit | 8015 (HTTP) | 8815 | 8415 |
| OpenMapKit | 8007 (HTTP) | 8807 | 8407 |
| Pan.do/ra | 8002 (HTTP) | 8802 | 8402 |
| Postfix | 25 (SMTP) | N/A | N/A |

View File

@ -78,7 +78,7 @@
<h2><a href="#"><img src="img/ODK.png" alt="Open Data Kit" title="Open Data Kit">Open Data Kit</a></h2>
<p><strong>Sběr dat s pomocí smartphone</strong>.<br>
<a href="http://geoodk.com/xlsform_converter.html">XLSForm</a> - online konverter XLS.<br>
<a href="httbap://geoodk.com">GeoODK Collect</a> - náhrada papírových dotazníků smartphonem.
<a href="http://geoodk.com">GeoODK Collect</a> - náhrada papírových dotazníků smartphonem.
</p>
<ul>
<li><strong>Login:</strong> <span class="login"></span></li>
@ -86,6 +86,16 @@
</ul>
</div>
<div class="c" id="opendatakit-clients">
<h2><a href="#"><img src="img/ODK.png" alt="Open Data Kit" title="Open Data Kit">Open Data Kit</a></h2>
<p>Mobilní aplikace<br>
<a href="https://play.google.com/store/apps/details?id=org.odk.collect.android"><img src="img/android.png" class="ico" alt="ODK Collect">ODK Collect pro Android</a><br>
</p>
<ul>
<li><strong>URL:</strong> <span class="clienturl"></span></li>
</ul>
</div>
<div class="c" id="openmapkit">
<h2><a href="#"><img src="img/OMK.png" alt="Open Map Kit" title="Open Map Kit">Open Data Kit</a></h2>
<p><strong>Sběr dat s pomocí smartphone</strong>.<br>

48
opendatakit.sh Executable file
View File

@ -0,0 +1,48 @@
#!/bin/sh
SOURCE_DIR=$(realpath $(dirname "${0}"))/opendatakit
# Check prerequisites
docker image ls | grep -q postgres || $(realpath $(dirname "${0}"))/postgres.sh
docker image ls | grep -q postfix || $(realpath $(dirname "${0}"))/postfix.sh
docker image ls | grep -q tomcat || $(realpath $(dirname "${0}"))/tomcat.sh
# Build Docker container
docker build -t opendatakit ${SOURCE_DIR}
# Create databases
export OPENDATAKIT_PWD=$(head -c 18 /dev/urandom | base64)
envsubst <${SOURCE_DIR}/createdb.sql | docker exec -i postgres psql
# Configure OpenDataKit
export OPENDATAKIT_ADMIN_USER=admin
export OPENDATAKIT_ADMIN_REALM=spotter
mkdir -p /srv/opendatakit/conf /srv/opendatakit/data
envsubst <${SOURCE_DIR}/srv/opendatakit/conf/jdbc.properties >/srv/opendatakit/conf/jdbc.properties
envsubst <${SOURCE_DIR}/srv/opendatakit/conf/security.properties >/srv/opendatakit/conf/security.properties
cp ${SOURCE_DIR}/srv/opendatakit/conf/server.xml /srv/opendatakit/conf/server.xml
cp ${SOURCE_DIR}/srv/opendatakit/update-ip.sh /srv/opendatakit/update-ip.sh
chown -R 8015:8015 /srv/opendatakit/conf /srv/opendatakit/data
# Create OpenDataKit service
cp ${SOURCE_DIR}/etc/init.d/opendatakit /etc/init.d/opendatakit
rc-update add opendatakit
service opendatakit start
# Update admin account
export OPENDATAKIT_ADMIN_PWD=$(head -c 12 /dev/urandom | base64)
export OPENDATAKIT_ADMIN_SALT=$(head -c 4 /dev/urandom | hexdump -e '"%x"') # Must be 8 characters
export OPENDATAKIT_ADMIN_BASIC_HASH=$(echo -n "${OPENDATAKIT_ADMIN_PWD}{${OPENDATAKIT_ADMIN_SALT}}" | sha1sum | tr -d " -")
export OPENDATAKIT_ADMIN_DIGEST_HASH=$(echo -n "${OPENDATAKIT_ADMIN_USER}:${OPENDATAKIT_ADMIN_REALM}:${OPENDATAKIT_ADMIN_PWD}" | md5sum | tr -d " -")
until docker logs opendatakit 2>&1 | grep -q 'org.apache.catalina.startup.Catalina.start'; do
sleep 1
done
envsubst <${SOURCE_DIR}/adminpwd.sql | docker exec -i postgres psql opendatakit
# Create nginx app definition
cp ${SOURCE_DIR}/etc/nginx/conf.d/opendatakit.conf /etc/nginx/conf.d/opendatakit.conf
service nginx reload
# Add portal application definition
portal-app-manager opendatakit "https://{host}:8415/aggregate/" "${OPENDATAKIT_ADMIN_USER}" "${OPENDATAKIT_ADMIN_PWD}"
portal-app-manager opendatakit-clients -p clienturl "http://{host}:8815/aggregate"

29
opendatakit/Dockerfile Normal file
View File

@ -0,0 +1,29 @@
FROM tomcat
MAINTAINER Disassembler <disassembler@dasm.cz>
RUN \
# Install build dependencies
apk --no-cache add --virtual .deps git git-lfs openjdk8 \
# Clone ODK aggregate
&& git clone --depth 1 https://github.com/opendatakit/aggregate.git /srv/odk \
# Compile Java web archive
&& cd /srv/odk \
&& cp gradle.properties.example gradle.properties \
&& ./gradlew war \
# Deploy web archive
&& mkdir /srv/tomcat/webapps/aggregate \
&& unzip build/libs/aggregate-*.war -d /srv/tomcat/webapps/aggregate \
# Create OS user
&& addgroup -S -g 8015 odk \
&& adduser -S -u 8015 -h /srv/tomcat -s /bin/false -g odk -G odk odk \
&& chown -R odk:odk /srv/tomcat/conf /srv/tomcat/logs /srv/tomcat/temp /srv/tomcat/webapps /srv/tomcat/work \
# Cleanup
&& apk --no-cache del .deps \
&& rm -rf /root/.gradle /root/.java /srv/odk
# VOLUME ["/srv/tomcat/.motech"]
EXPOSE 8015
USER odk
WORKDIR /srv/tomcat
CMD ["catalina.sh", "run"]

1
opendatakit/adminpwd.sql Normal file
View File

@ -0,0 +1 @@
UPDATE _registered_users SET "BASIC_AUTH_PASSWORD" = '${OPENDATAKIT_ADMIN_BASIC_HASH}', "BASIC_AUTH_SALT" = '${OPENDATAKIT_ADMIN_SALT}', "DIGEST_AUTH_PASSWORD" = '${OPENDATAKIT_ADMIN_DIGEST_HASH}' WHERE "LOCAL_USERNAME" = '${OPENDATAKIT_ADMIN_USER}';

4
opendatakit/createdb.sql Normal file
View File

@ -0,0 +1,4 @@
CREATE ROLE opendatakit NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN ENCRYPTED PASSWORD '${OPENDATAKIT_PWD}';
CREATE DATABASE opendatakit;
REVOKE ALL ON DATABASE opendatakit FROM public;
ALTER DATABASE opendatakit OWNER TO opendatakit;

View File

@ -0,0 +1,29 @@
#!/sbin/openrc-run
description="OpenDataKit docker container"
depend() {
need docker net postgres
use dns logger netmount postfix
}
start_pre() {
/srv/opendatakit/update-ip.sh
}
start() {
/usr/bin/docker run -d --rm \
--name opendatakit \
-h opendatakit \
--link postfix \
--link postgres \
-p 127.0.0.1:8015:8015 \
-v /srv/opendatakit/conf/server.xml:/srv/tomcat/conf/server.xml \
-v /srv/opendatakit/conf/jdbc.properties:/srv/tomcat/webapps/aggregate/WEB-INF/classes/jdbc.properties \
-v /srv/opendatakit/conf/security.properties:/srv/tomcat/webapps/aggregate/WEB-INF/classes/security.properties \
opendatakit
}
stop() {
/usr/bin/docker stop opendatakit
}

View File

@ -0,0 +1,11 @@
server {
listen [::]:8815 ipv6only=off;
listen [::]:8415 ssl http2 ipv6only=off;
access_log /var/log/nginx/opendatakit.access.log;
error_log /var/log/nginx/opendatakit.error.log;
location / {
proxy_pass http://127.0.0.1:8015;
}
}

View File

@ -0,0 +1,6 @@
jdbc.driverClassName=org.postgresql.Driver
jdbc.resourceName=jdbc/odk_aggregate
jdbc.url=jdbc:postgresql://postgres/opendatakit?autoDeserialize=true
jdbc.username=opendatakit
jdbc.password=${OPENDATAKIT_PWD}
jdbc.schema=public

View File

@ -0,0 +1,48 @@
# Either basic or digest
security.server.deviceAuthentication=basic
# Choose whether to secure everything with https or allow http access.
#
# NOTE: changes also needed to:
# -- server.xml (Tomcat configuration file) to set up the secure channel
#
# issue 648 - REQUIRES_INSECURE_CHANNEL is now the default instead of ANY_CHANNEL
# there are various edge cases that have not been tested in the UI for
# allowing arbitrary accesses, as the session cookie and authentication
# do get set for a specific http: or https: scheme and are not transferrable.
#
# should be REQUIRES_SECURE_CHANNEL but can't unless SSL is available.
security.server.secureChannelType=REQUIRES_INSECURE_CHANNEL
#security.server.secureChannelType=REQUIRES_SECURE_CHANNEL
# either REQUIRES_INSECURE_CHANNEL to secure nothing
# or REQUIRES_SECURE_CHANNEL to secure everything
# or perhaps ANY_CHANNEL when running through a proxy server
security.server.channelType=REQUIRES_INSECURE_CHANNEL
#security.server.channelType=REQUIRES_SECURE_CHANNEL
# When running under Tomcat, you need to set the hostname and port for
# the server so that the background tasks can generate properly-constructed
# links in their documents and in their publications to the
# external services.
#
# This is configured during install. If blank, discovers an IP address
security.server.hostname=
security.server.port=8815
security.server.securePort=8415
wink.handlersFactoryClass=org.opendatakit.aggregate.odktables.impl.api.wink.AppEngineHandlersFactory
# e-mail of designated superuser. This must be a user that has an OAuth2
# login hosted by a remote server (i.e., this must be a gmail account).
# this should be of the form: 'mailto:user@gmail.com'
security.server.superUser=
# Define a superUserUsername to insert an ODK Aggregate username that can
# access the server. The initial password for this username is 'aggregate'
security.server.superUserUsername=${OPENDATAKIT_ADMIN_USER}
# realm definition
# realmString -- what should be sent to users when BasicAuth or DigestAuth is done
security.server.realm.realmString=${OPENDATAKIT_ADMIN_REALM}

View File

@ -0,0 +1,143 @@
<?xml version='1.0' encoding='utf-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" at this level.
Documentation at /docs/config/server.html
-->
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<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.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<!-- A "Service" is a collection of one or more "Connectors" that share
a single "Container" Note: A "Service" is not itself a "Container",
so you may not define subcomponents such as "Valves" at this level.
Documentation at /docs/config/service.html
-->
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
<Connector port="8015" protocol="HTTP/1.1"
connectionTimeout="20000"
proxyName="127.0.0.1"
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" />
<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host).
Documentation at /docs/config/engine.html -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- 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"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
</Engine>
</Service>
</Server>

View File

@ -0,0 +1,4 @@
#!/bin/sh
URL=$(ip route get 1 | awk '{print $NF;exit}')
sed -i "s|\(^\s\+proxyName\).*|\1=\"${URL}\"|" /srv/opendatakit/conf/server.xml