You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by vo...@apache.org on 2019/06/29 13:38:40 UTC
[fineract] 01/05: Create one-touch deploy with docker
This is an automated email from the ASF dual-hosted git repository.
vorburger pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
commit 357820a7a755dce27d6d2707f29ffd21c71f54d1
Author: conradsp <sc...@gmail.com>
AuthorDate: Thu Jun 20 08:37:18 2019 -0500
Create one-touch deploy with docker
---
docker/Dockerfile | 28 +++
docker/README.md | 25 ++
docker/build.gradle | 553 +++++++++++++++++++++++++++++++++++++++++
docker/docker-compose.yml | 24 ++
docker/initdb/01-databases.sql | 6 +
docker/server.xml | 191 ++++++++++++++
6 files changed, 827 insertions(+)
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644
index 0000000..5488e6f
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,28 @@
+FROM bitnami/tomcat:7.0.94 as fineract
+
+USER root
+RUN apt-get update -qq && apt-get install -y git openjdk-8-jdk wget
+ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/jre
+
+RUN git clone https://github.com/apache/fineract.git
+COPY build.gradle fineract/fineract-provider
+
+# To use for local fineract development (instead of installing from the latest code from Github)
+# 1) Copy Dockerfile, docker-compose.yml, and the initdb directory to the root of your project (/fineract)
+# 2) Edit Dockerfile in /fineract - comment out the 2 lines above (RUN git clone and COPY build.gradle)
+# 3) Uncomment the 2 lines below
+# 4) Update your local copy of build.gradle and replace all references to localhost with fineractmysql
+
+#RUN mkdir fineract
+#COPY . fineract
+
+WORKDIR fineract
+RUN ./gradlew clean war
+RUN mv build/libs/fineract-provider.war /opt/bitnami/tomcat/webapps
+
+RUN keytool -genkey -keyalg RSA -alias tomcat -keystore /opt/bitnami/tomcat/tomcat.keystore -keypass xyz123 -storepass xyz123 -noprompt -dname "CN=Fineract, OU=Fineract, O=Fineract, L=Unknown, ST=Unknown, C=Unknown"
+COPY server.xml /opt/bitnami/tomcat/conf
+RUN chmod 664 /opt/bitnami/tomcat/conf/server.xml
+WORKDIR /opt/bitnami/tomcat/lib
+RUN wget http://central.maven.org/maven2/org/drizzle/jdbc/drizzle-jdbc/1.3/drizzle-jdbc-1.3.jar
+
diff --git a/docker/README.md b/docker/README.md
new file mode 100644
index 0000000..aae3739
--- /dev/null
+++ b/docker/README.md
@@ -0,0 +1,25 @@
+Installing Fineract with Docker and docker-compose
+
+Prerequisites
+=============
+* docker and docker-compose installed on your machine
+
+
+Installing a new Fineract instance
+==================================
+
+* Clone the Fineract Github repository
+* Navigate to the docker directory
+* Run the following commands:
+ * docker-compose build
+ * docker-compose up -d
+* Fineract will run at https://localhost:8443/fineract-provider
+
+
+Using docker-compose for development
+====================================
+
+* Copy Dockerfile, docker-compose.yml, and the initdb directory to the root of your project (/fineract)
+* Edit Dockerfile in /fineract - comment out the 2 lines (RUN git clone and COPY build.gradle)
+* Uncomment the 2 lines in Dockerfile (RUN mkdir fineract, COPY . fineract)
+* Update your local copy of build.gradle and replace all references to localhost with fineractmysql
diff --git a/docker/build.gradle b/docker/build.gradle
new file mode 100644
index 0000000..d0964e8
--- /dev/null
+++ b/docker/build.gradle
@@ -0,0 +1,553 @@
+/**
+ * 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.
+ */
+description = '''\
+Run as:
+gradle clean tomcatrunwar
+'''
+buildscript {
+ repositories {
+ jcenter()
+ mavenCentral()
+ maven { url "https://plugins.gradle.org/m2/" }
+ }
+
+ dependencies {
+ classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:1.0',
+ 'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0',
+ 'org.zeroturnaround:gradle-jrebel-plugin:1.1.2',
+ 'org.springframework.boot:spring-boot-gradle-plugin:1.1.6.RELEASE' // also change springDataJpaVersion below
+ classpath 'org.apache.openjpa:openjpa-all:2.4.1'
+ classpath 'at.schmutterer.oss.gradle:gradle-openjpa:0.2.0'
+ classpath 'gradle.plugin.org.nosphere.apache:creadur-rat-gradle:0.2.2'
+ }
+}
+
+apply plugin: "org.nosphere.apache.rat"
+apply plugin: 'rebel'
+apply plugin: 'license'
+apply plugin: 'war'
+apply plugin: 'spring-boot'
+apply plugin: 'eclipse'
+apply plugin: 'idea'
+apply plugin: 'tomcat'
+apply plugin: 'project-report'
+apply plugin: 'java'
+apply plugin: 'openjpa'
+apply plugin: 'pmd'
+apply plugin: 'findbugs'
+
+/* define the valid syntax level for source files */
+sourceCompatibility = JavaVersion.VERSION_1_8
+/* define binary compatibility version */
+targetCompatibility = JavaVersion.VERSION_1_8
+
+project.ext.springBootVersion = '1.2.8.RELEASE'
+project.ext.springVersion = '4.1.9.RELEASE'
+project.ext.springOauthVersion = '2.0.4.RELEASE'
+project.ext.jerseyVersion = '1.17'
+project.ext.springDataJpaVersion = '1.7.0.RELEASE' // also change spring-boot-gradle-plugin version above
+
+project.ext.mysqlUser='root'
+project.ext.mysqlPassword='mysql'
+
+
+group = 'org.apache.fineract'
+buildDir = new File(rootProject.projectDir, "../build")
+repositories {
+ jcenter()
+ // mavenLocal() // useful for local dev using MariaDB4j SNAPSHOTs (not needed for real-world non-SNAPHOT builds)
+}
+openjpa {
+ files = fileTree(sourceSets.main.output.classesDir).matching {
+ include '**/AbstractPersistableCustom.class'
+ include '**/domain/*.class'
+
+ }
+ enforcePropertyRestrictions = true
+}
+
+rat {
+ xmlOutput = false
+ htmlOutput = false
+ plainOutput = true
+ verbose = false
+// inputDir = './..'
+ reportDir = new File(buildDir,'reports/rat')
+ excludes = [
+ '**/licenses/**',
+ '**/*.md',
+ '**/*.github/*',
+ '**/MANIFEST.MF',
+ '**/*.txt',
+ '**/*.log',
+ '**/fineractdev-eclipse-preferences.epf',
+ '**/template-expected.html',
+ '**/template.mustache',
+ '**/.classpath',
+ '**/.project',
+ '**/.idea/**',
+ '**/*.ipr',
+ '**/*.iws',
+ '**/.settings/**',
+ '**/bin/**',
+ '**/.git/**',
+ '**/.gitignore',
+ '**/.gitkeep',
+ '**/*.iml',
+ //Notice files
+ '**/NOTICE_RELEASE',
+ '**/NOTICE_SOURCE',
+ // Swagger License
+ '**/src/main/resources/swagger-ui/**',
+ // gradle
+ '**/.gradle/**',
+ '**/gradlew',
+ '**/gradlew.bat',
+ '**/gradle/wrapper/gradle-wrapper.properties',
+ '**/caches/**',
+ '**/daemon/**',
+ '**/native/**',
+ '**/wrapper/**',
+ '**/build/**',
+
+ //Api Docs
+ '**/api-docs/*.*',
+ '**/docs/system-architecture/.htaccess',
+ '**/docs/system-architecture/404.html',
+ '**/docs/system-architecture/index.html',
+ '**/docs/system-architecture/**/*.xml',
+ '**/bootstrap-3.0.0/assets/application.js',
+ '**/system-architecture/js/plugins.js',
+
+ //Apache License
+ '**/bootstrap-3.0.0/assets/less.js',
+ '**/css/bootstrap-3.0.0/**/*.*',
+
+ //Public Domain See http://www.JSON.org/js.html
+ '**/bootstrap-3.0.0/assets/json2.js.htm',
+
+ // MIT License
+ '**/modernizr-2.6.2.min.js',
+ '**/css/normalize.css',
+ '**/assets/filesaver.js',
+ '**/css/fonts/glyphicons-halflings-regular.svg',
+ '**/assets/jszip.js',
+ '**/assets/jquery.js',
+ '**/api-docs/jquery-1.7.min.js',
+ '**/css/toc-0.1.2/**/*.*',
+ '**/docs/system-architecture/css/main.css',
+ '**/system-architecture/js/vendor/jquery-1.9.1.min.js',
+ '**/system-architecture/js/vendor/toc-0.1.2/jquery.toc.min.js',
+ '**/assets/respond.min.js',
+ '**/assets/html5shiv.js',
+
+ //BSD License
+ '**/assets/uglify.js',
+ //Ignore out folder
+ '**/out/**'
+ ]
+}
+
+configurations {
+ providedRuntime // needed for Spring Boot executable WAR
+ providedCompile
+ compile() {
+ exclude module: 'hibernate-entitymanager'
+ exclude module: 'hibernate-validator'
+ exclude module: 'activation'
+ exclude module: 'bcmail-jdk14'
+ exclude module: 'bcprov-jdk14'
+ exclude module: 'bctsp-jdk14'
+ exclude module: 'bval-core'
+ exclude module: 'org.apache.bval.bundle'
+ exclude module: 'bval-jsr303'
+ exclude module: 'c3p0'
+ exclude module: 'stax-api'
+ exclude module: 'jaxb-api'
+ exclude module: 'jaxb-impl'
+ exclude module: 'jboss-logging'
+ exclude module: 'itext-rtf'
+ exclude module: 'classworlds'
+ exclude module: 'jcl-over-slf4j'
+ exclude module: 'jul-to-slf4j'
+ exclude module: 'serp'
+ }
+ runtime
+ all*.exclude group: 'commons-logging'
+}
+/* Pick up dependencies based on the environemnt, defaults to production */
+if (project.hasProperty('env') && project.getProperty('env') == 'dev') {
+ apply from: 'dev-dependencies.gradle'
+} else {
+ apply from: 'dependencies.gradle'
+}
+
+/* Enable Oauth2 authentication based on environment, default to HTTP basic auth */
+if (project.hasProperty('security') && project.getProperty('security') == 'oauth') {
+ if(project.hasProperty('twofactor') && project.getProperty('twofactor') == 'enabled') {
+ copy {
+ from './properties/oauth/twofactor/'
+ into 'src/main/resources/'
+ include '*.properties'
+ }
+ } else {
+ copy {
+ from './properties/oauth/'
+ into 'src/main/resources/'
+ include '*.properties'
+ }
+ }
+} else {
+ if(project.hasProperty('twofactor') && project.getProperty('twofactor') == 'enabled') {
+ copy {
+ from './properties/basicauth/twofactor/'
+ into 'src/main/resources/'
+ include '*.properties'
+ }
+ } else {
+ copy {
+ from './properties/basicauth/'
+ into 'src/main/resources/'
+ include '*.properties'
+ }
+ }
+}
+
+task dist(type:Zip){
+ baseName = 'fineractplatform'
+ version = qualifyVersionIfNecessary(releaseVersion)
+ includeEmptyDirs = true
+ from('../') {
+ fileMode = 0755
+ include '*.md'
+ }
+ from('src/main/dist') {
+ fileMode = 0755
+ include '*'
+ }
+ from('../apps') {
+ fileMode = 0755
+ include '**/*'
+ into('apps')
+ }
+ from('../api-docs/') {
+ fileMode = 0755
+ include '*'
+ into('api-docs')
+ }
+ from('../fineract-db/') {
+ fileMode = 0755
+ include '*.sql'
+ into('database')
+ }
+ from('src/main/resources/sql/migrations') {
+ fileMode = 0755
+ include '**/*'
+ into('database/migrations')
+ }
+
+ from war.outputs.files
+ into(baseName + '-' + version)
+}
+
+compileJava{
+ dependsOn rat
+}
+pmd {
+ sourceSets = [sourceSets.main]
+ ignoreFailures = true
+}
+findbugs {
+ ignoreFailures = true
+ sourceSets = [sourceSets.main]
+}
+
+war {
+ from('../licenses/binary/') { // notice the parens
+ into "WEB-INF/licenses/binary/" // no leading slash
+ }
+ from('../LICENSE_RELEASE') { // notice the parens
+ into "WEB-INF/" // no leading slash
+ }
+ from('../NOTICE_RELEASE') { // notice the parens
+ into "WEB-INF/" // no leading slash
+ }
+ rename ('LICENSE_RELEASE', 'LICENSE')
+ rename ('NOTICE_RELEASE', 'NOTICE')
+
+ from('../DISCLAIMER') { // notice the parens
+ into "WEB-INF/" // no leading slash
+ }
+ war.finalizedBy(bootRepackage)
+}
+
+license {
+ header rootProject.file('../APACHE_LICENSETEXT.md')
+ excludes(["**/*.html", "**/*.mustache", "**/package-info.java", "**/keystore.jks", "**/swagger-ui/**"])
+ strictCheck true
+}
+
+task licenseFormatBuildScripts (type:nl.javadude.gradle.plugins.license.License) {
+ source = fileTree(dir: '../', includes: ['**/*.bat', '**/*.sh', '**/*.sql'])
+}
+licenseFormat.dependsOn licenseFormatBuildScripts
+
+tomcatRun {
+ httpPort = 8080
+ httpsPort = 8443
+ stopPort = 8081
+ stopKey= 'stopKey'
+ enableSSL = true
+ configFile = file('src/test/resources/META-INF/context.xml')
+}
+
+tomcatRunWar {
+ httpPort = 8080
+ httpsPort = 8443
+ stopPort = 8081
+ stopKey= 'stopKey'
+ enableSSL = true
+ keystoreFile = file('src/main/resources/keystore.jks')
+ keystorePass = 'openmf'
+ configFile = file('src/test/resources/META-INF/context.xml')
+}
+
+/* http://stackoverflow.com/questions/19653311/jpa-repository-works-in-idea-and-production-but-not-in-gradle */
+sourceSets.main.output.resourcesDir = sourceSets.main.output.classesDir
+sourceSets.test.output.resourcesDir = sourceSets.test.output.classesDir
+
+/* Exclude maria db and embedded tomcat related files for non dev builds */
+if (!(project.hasProperty('env') && project.getProperty('env') == 'dev')) {
+sourceSets {
+ main {
+ java {
+ exclude '**/Server*'
+ exclude '**/MariaDB4j*'
+ exclude '**/EmbeddedTomcatWithSSLConfiguration.java'
+ }
+ }
+ test {
+ java {
+ exclude '**/core/boot/tests/**'
+ }
+ }
+}
+}
+
+sourceSets {
+ integrationTest {
+ compileClasspath += main.output + test.output
+ runtimeClasspath += main.output + test.output
+ }
+}
+
+configurations {
+ integrationTestCompile.extendsFrom testCompile
+ integrationTestRuntime.extendsFrom testRuntime
+}
+
+task integrationTest(type:Test){
+ description = "Run integration tests (located in src/integrationTest/java). Starts tomcat in daemon mode before executing the tests."
+ it.dependsOn war
+ doFirst {
+ tomcatRunWar.daemon = true
+ tomcatRunWar.execute()
+ }
+ testClassesDir = project.sourceSets.integrationTest.output.classesDir
+ classpath = project.sourceSets.integrationTest.runtimeClasspath
+}
+
+
+import groovy.sql.Sql
+
+repositories {
+ mavenCentral()
+}
+configurations {
+ driver
+}
+dependencies {
+ driver 'org.drizzle.jdbc:drizzle-jdbc:1.3'
+}
+
+test {
+ filter {
+ //includeTestsMatching "org.apache.fineract.infrastructure.configuration.spring.SpringConfigurationTest.*"
+ includeTestsMatching "org.apache.fineract.template.TemplateMergeServiceTest.*"
+ }
+}
+
+URLClassLoader loader = GroovyObject.class.classLoader
+configurations.driver.each {File file ->
+ loader.addURL(file.toURL())
+}
+
+task createDB<<{
+ description= "Creates the Database. Needs database name to be passed (like: -PdbName=someDBname)"
+ def sql = Sql.newInstance( 'jdbc:mysql:thin://fineractmysql:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
+ sql.execute( 'create database '+"`$dbName`" )
+}
+
+task dropDB<<{
+ description= "Drops the specified database. The database name has to be passed (like: -PdbName=someDBname)"
+ def sql = Sql.newInstance( 'jdbc:mysql:thin://fineractmysql:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
+ sql.execute( 'DROP DATABASE '+"`$dbName`")
+}
+task setBlankPassword<<{
+ def sql = Sql.newInstance( 'jdbc:mysql:thin://fineractmysql:3306/', mysqlUser, mysqlPassword, 'org.drizzle.jdbc.DrizzleDriver' )
+ sql.execute('USE `mifosplatform-tenants`')
+ sql.execute('UPDATE mifosplatform-tenants.tenants SET schema_server = \'fineractmysql\', schema_server_port = \'3306\', schema_username = \'mifos\', schema_password = \'mysql\' WHERE id=1;')
+}
+
+
+apply plugin: 'flyway'
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath "org.flywaydb:flyway-gradle-plugin:3.0" // version upgraded during Spring Boot & MariaDB4j work, as prev. used v0.2 didn't work well after *.sql moved from fineract-db to fineract-provider/src/main/resources (new version also has clearer errors, e.g. in case of missing DB)
+
+ // NOT classpath 'org.drizzle.jdbc:drizzle-jdbc:1.3' as it is not compatible with Flyway 3.1+ (only up to 3.0)
+ // We require Flyway 3.1+ because =< 3.0 is not compatible with current Gradle versions (only ancient ones we originally used to use).
+ // Using LGPL ConnectorJ ()org.mariadb.jdbc:mariadb-java-client) instead of the BSD licensed drizzle-jdbc *IS OK* at Apache.org,
+ // as long as it's only used as a test library by developers at build time, and not end-user distributed, and optional.
+ // So it's OK here, but would not be as a default runtime dependency and in the dist JAR/WAR.
+ // see https://issues.apache.org/jira/browse/LEGAL-462
+ // see https://issues.apache.org/jira/browse/FINERACT-761
+ // see https://github.com/flyway/flyway/issues/2332
+ // see https://github.com/krummas/DrizzleJDBC/issues/46
+ // see https://github.com/apache/fineract/pull/525
+ // see https://github.com/apache/fineract/pull/550
+ classpath 'org.mariadb.jdbc:mariadb-java-client:2.4.1'
+ }
+}
+
+
+flyway {
+ url = "jdbc:mariadb://fineractmysql:3306/mifostenant-default"
+ driver = "org.mariadb.jdbc.Driver"
+ user = mysqlUser
+ password = mysqlPassword
+}
+
+task migrateTenantDB<<{
+ description="Migrates a Tenant DB. Optionally can pass dbName. Defaults to 'mifostenant-default' (Example: -PdbName=someTenantDBname)"
+
+ def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/core_db'
+ def tenantDbName = 'mifostenant-default';
+ if (rootProject.hasProperty("dbName")) {
+ tenantDbName = rootProject.getProperty("dbName")
+ }
+
+ flyway.url= "jdbc:mariadb://fineractmysql:3306/$tenantDbName"
+ flyway.driver = "org.mariadb.jdbc.Driver"
+ flyway.locations= [filePath]
+ /**We use ${ as the prefix for strecthy reporting, do not want them to be interpreted by Flyway**/
+ flyway.placeholderPrefix = "\$\${"
+ flywayMigrate.execute()
+}
+
+task showTenantDBInfo<<{
+ description="Shows the migration info for a Tenant DB. Optionally can pass dbName. Defaults to 'mifostenant-default' (Example: -PdbName=someTenantDBname)"
+
+ def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/core_db'
+ def tenantDbName = 'mifostenant-default';
+ if (rootProject.hasProperty("dbName")) {
+ tenantDbName = rootProject.getProperty("dbName")
+ }
+
+ flyway.url= "jdbc:mariadb://fineractmysql:3306/$tenantDbName"
+ flyway.driver = "org.mariadb.jdbc.Driver"
+ flyway.locations= [filePath]
+ flywayInfo.execute()
+}
+
+
+task migrateTenantListDB<<{
+ description="Migrates a Tenant List DB. Optionally can pass dbName. Defaults to 'mifosplatform-tenants' (Example: -PdbName=someDBname)"
+
+ def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/list_db'
+ def tenantsDbName = 'mifosplatform-tenants';
+ if (rootProject.hasProperty("dbName")) {
+ tenantsDbName = rootProject.getProperty("dbName")
+ }
+
+ flyway.url= "jdbc:mariadb://fineractmysql:3306/$tenantsDbName"
+ flyway.driver = "org.mariadb.jdbc.Driver"
+ flyway.locations= [filePath]
+
+ flywayMigrate.execute()
+}
+
+task showTenantListDBInfo<<{
+ description="Shows the migration info for a List DB. Optionally can pass dbName. Defaults to 'mifosplatform-tenants' (Example: -PdbName=someDBname)"
+
+ def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/list_db'
+ def tenantsDbName = 'mifosplatform-tenants';
+ if (rootProject.hasProperty("dbName")) {
+ tenantsDbName = rootProject.getProperty("dbName")
+ }
+
+ flyway.url= "jdbc:mariadb://fineractmysql:3306/$tenantsDbName"
+ flyway.driver = "org.mariadb.jdbc.Driver"
+ flyway.locations= [filePath]
+ flywayInfo.execute()
+}
+
+task repairTenantDB<<{
+ description="repair migrate"
+
+ def filePath = "filesystem:$projectDir" + '/src/main/resources/sql/migrations/list_db'
+ def tenantsDbName = 'mifosplatform-tenants';
+ if (rootProject.hasProperty("dbName")) {
+ tenantsDbName = rootProject.getProperty("dbName")
+ }
+
+ flyway.url= "jdbc:mariadb://fineractmysql:3306/$tenantsDbName"
+ flyway.driver = "org.mariadb.jdbc.Driver"
+ flyway.locations= [filePath]
+ flywayRepair.execute()
+}
+
+/*
+* Support publication of artifacts versioned by topic branch.
+* CI builds supply `-P BRANCH_NAME=<TOPIC>` to gradle at build time.
+* If <TOPIC> starts with 'MIFOSX-', change version
+* from BUILD-SNAPSHOT => <TOPIC>-SNAPSHOT
+* e.g. 1.1.0.BUILD-SNAPSHOT => 1.0.0.MIFOSX-1234-SNAPSHOT
+*/
+def qualifyVersionIfNecessary(version) {
+
+ if (rootProject.hasProperty("BRANCH_NAME")) {
+ def qualifier = rootProject.getProperty("BRANCH_NAME")
+ if (qualifier.startsWith("MIFOSX-")) {
+ return version.replace('BUILD', qualifier)
+ }
+ }
+ return version
+}
+
+springBoot {
+ mainClass = 'org.apache.fineract.ServerWithMariaDB4jApplication'
+}
+bootRepackage {
+ mainClass = 'org.apache.fineract.ServerWithMariaDB4jApplication'
+}
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
new file mode 100644
index 0000000..912124b
--- /dev/null
+++ b/docker/docker-compose.yml
@@ -0,0 +1,24 @@
+version: '3.7'
+services:
+ fineractmysql:
+ image: mysql:5.7
+ volumes:
+ - dbdata:/var/lib/mysql
+ - ./initdb:/docker-entrypoint-initdb.d
+ restart: always
+ environment:
+ MYSQL_ROOT_PASSWORD: mysql
+ MYSQL_USER: root
+ MYSQL_PASSWORD: mysql
+ ports:
+ - "3306:3306"
+ fineract-server:
+ build:
+ context: .
+ target: fineract
+ ports:
+ - 443:443
+ depends_on:
+ - fineractmysql
+volumes:
+ dbdata:
\ No newline at end of file
diff --git a/docker/initdb/01-databases.sql b/docker/initdb/01-databases.sql
new file mode 100644
index 0000000..e4fa5fb
--- /dev/null
+++ b/docker/initdb/01-databases.sql
@@ -0,0 +1,6 @@
+# create databases
+CREATE DATABASE IF NOT EXISTS `mifosplatform-tenants`;
+CREATE DATABASE IF NOT EXISTS `mifostenant-default`;
+
+# create root user and grant rights
+GRANT ALL ON *.* TO 'root'@'%';
\ No newline at end of file
diff --git a/docker/server.xml b/docker/server.xml
new file mode 100644
index 0000000..3b4a0fc
--- /dev/null
+++ b/docker/server.xml
@@ -0,0 +1,191 @@
+<?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 type="javax.sql.DataSource"
+ name="jdbc/mifosplatform-tenants"
+ factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
+ driverClassName="org.drizzle.jdbc.DrizzleDriver"
+ url="jdbc:mysql:thin://fineractmysql:3306/mifosplatform-tenants"
+ username="root"
+ password="mysql"
+ initialSize="3"
+ maxActive="10"
+ maxIdle="6"
+ minIdle="3"
+ validationQuery="SELECT 1"
+ testOnBorrow="true"
+ testOnReturn="true"
+ testWhileIdle="true"
+ timeBetweenEvictionRunsMillis="30000"
+ minEvictableIdleTimeMillis="60000"
+ logAbandoned="true"
+ suspectTimeout="60"
+ />
+ </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
+ 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="8080" protocol="HTTP/1.1"
+ connectionTimeout="20000"
+ 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. The default
+ SSLImplementation will depend on the presence of the APR/native
+ library and the useOpenSSL attribute of the
+ AprLifecycleListener.
+ Either JSSE or OpenSSL style configuration may be used regardless of
+ the SSLImplementation selected. JSSE style configuration is used below.
+ -->
+ <Connector protocol="org.apache.coyote.http11.Http11Protocol"
+ port="8443" maxThreads="200" scheme="https"
+ secure="true" SSLEnabled="true"
+ keystoreFile="/opt/bitnami/tomcat/tomcat.keystore"
+ keystorePass="xyz123"
+ clientAuth="false" sslProtocol="TLS"
+ URIEncoding="UTF-8"
+ compression="force"
+ compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css"/>
+ <!--
+ <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
+ maxThreads="150" SSLEnabled="true">
+ <SSLHostConfig>
+ <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
+ type="RSA" />
+ </SSLHostConfig>
+ </Connector>
+ -->
+ <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
+ This connector uses the APR/native implementation which always uses
+ OpenSSL for TLS.
+ Either JSSE or OpenSSL style configuration may be used. OpenSSL style
+ configuration is used below.
+ -->
+ <!--
+ <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
+ maxThreads="150" SSLEnabled="true" >
+ <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
+ <SSLHostConfig>
+ <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
+ certificateFile="conf/localhost-rsa-cert.pem"
+ certificateChainFile="conf/localhost-rsa-chain.pem"
+ type="RSA" />
+ </SSLHostConfig>
+ </Connector>
+ -->
+
+ <!-- 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 "%r" %s %b" />
+
+ </Host>
+ </Engine>
+ </Service>
+</Server>
\ No newline at end of file