Multiple app instances with separate databases within the same Tomcat

Hi
Currently, my application (app) is running in a VPS and now I want to deploy another instance, say UAT version within the same tomcat server but of course that UAT version will use it’s own database.

A. Here is the approach.

  1. Rename the module prefix
  2. change the database connections

B. Here is what I have done:

renamed the application prefix to appUat and used a separate database connection for this version.

Here is what I see:
gradle for :app

task buildWar(type: CubaWarBuilding) {
    appHome = '/home/tomcat/apache-tomcat-9.0.29/webapps'
    singleWar = false
    includeContextXml = true
    includeJdbcDriver = true
    appProperties = [
            'cuba.automaticDatabaseUpdate': true,
            'cuba.webPort': 8080,
            'cuba.connectionUrlList': 'http://localhost:8080/app-core'
     ]
}

core context.xml database connection url
url="jdbc:postgresql://localhost/appDatabase"

gradle for :appUat

task buildWar(type: CubaWarBuilding) {
    appHome = '/home/tomcat/apache-tomcat-9.0.29/webapps'
    singleWar = false
    includeContextXml = true
    includeJdbcDriver = true
    appProperties = [
            'cuba.automaticDatabaseUpdate': true,
            'cuba.webPort': 8080,
            'cuba.connectionUrlList': 'http://localhost:8080/appUat-core'
    ]
}

the core conext.xml is updated with the database name related to Uat version

url="jdbc:postgresql://localhost/appDatabaseUat"

However, when I deploy the appUat to my server, the appUat application still connects to appDatabase instead of appDatabaseUat

Question:

  1. Is this approach right and safe or there is some other better approach?
  2. How can I connect to the Uat database in the scenario descrived in (B) above?

Hi Mortoza,

If you want to build WAR files with specific database connection parameters, use the coreContextXmlPath parameter of the buildWar task. It allows you to specify a file which will go to the WAR instead of context.xml currently used in your dev environment.

Thank you Konstantin.

So the buildWar task in build.gradle may look like this:

task buildWar(type: CubaWarBuilding) {
    appHome = '${app.home}'
    singleWar = true
    includeContextXml = true
    includeJdbcDriver = true
    appProperties = ['cuba.automaticDatabaseUpdate': true]
    coreContextXmlPath = 'modules/core/web/META-INF/war-context.xml'
}

I am considering following two files to use when appropriate:

  1. prod-context.xml
  2. uat-context.xml

image

Is it allowed that I keep 2 files in the same project and use one which is relevant for the instance I am deploying e.g. PROD and UAT? Is there any rule or naming convention for the war-context.xml file?

Context file: prod-context.xml

<Context>
    <Resource driverClassName="org.postgresql.Driver"
              maxIdle="2"
              maxTotal="20"
              maxWaitMillis="5000"
              name="jdbc/CubaDS"
              username="user1"/>
              password="passwd1"
              type="javax.sql.DataSource"
              url="jdbc:postgresql://144.554.54.55/app"
    <Manager pathname=""/>
</Context>

Context file: uat-context.xml

<Context>
    <Resource driverClassName="org.postgresql.Driver"
              maxIdle="2"
              maxTotal="20"
              maxWaitMillis="5000"
              name="jdbc/CubaDS"
              username="user1"/>
              password="passwd1"
              type="javax.sql.DataSource"
              url="jdbc:postgresql://144.554.54.55/uatapp"
    <Manager pathname=""/>
</Context>

Of course you can have multiple files with different database properties.
I would recommend also creating separate tasks for using these files, e.g. the first task managed by Studio, it always has buildWar name, and the second you can just copy-paste and change the name, e.g.

task buildProdWar(type: CubaWarBuilding) {
    //...
    coreContextXmlPath = 'modules/core/web/META-INF/prod-context.xml'
}

Then you can build the prod WAR from the command line:

$ ./gradlew buildProdWar

Awesome, thank you. I shall give a try.

It just worked perfectly! Thank you so much Konstantin for your help.