Running Tomcat with different resources for different environments

1.4k views Asked by At

I have an application-level context.xml with three different databases connections, and my application successfully connects and works fine against those databases. The war file is added to a Tomcat Docker image, and the container runs great.

But, what I really need is the ability to bring up my WAR file with different context.xml files in different environments (Development, QA, and Production). Each environment has its own set of three database connections (i.e. unique URLs/usernames/passwords but the same resource names).

Is there a mechanism in Tomcat where I can pass an environment variable into the Tomcat container at startup, and specify which context file to use? e.g. if I had META-INF/context_dev.xml, META-INF/context_qa.xml, and META-INF/context_prod.xml.

Or, is there some other different kind of mechanism I should be using to have one Docker image that works with three different sets of database resources?

Thanks, John

2

There are 2 answers

2
Nicolas Bousquet On

In containers and docker as well as kubernetes, ENV variables are the way to go to pass configuration to your container.

You set your tomcat so it also take them into account and use the ENV name in the file.

For tomcat (independtly of having containers or not) an explanation on how to pass env variables is shown there: Tomcat 8 - context.xml use Environment Variable in Datasource

How to pass env variable to your container: How do I pass environment variables to Docker containers?

Then you can pass your env variable in command line with RAW docker or use an .env file. Changing the command like with different values for the ENV variable or just a different .env file to use will do the trick.

1
John Fisher On

I made a solution that will work for me with minimal changes, taking as inspiration the suggestions I received above. Basically, I put ALL the resources for ALL the environments in context.xml, then I named them like such:

<Resource
   name="${PRODENV}/mydb1"
   XXXXXXX
/>

<Resource
   name="${PRODENV}/mydb2"
   XXXXXXX
/>

<Resource
   name="${QAENV}/mydb1"
   XXXXXXX
/>

<Resource
   name="${QAENV}/mydb2"
   XXXXXXX
/>

Then, when I start the container, I just add -DPRODENV=jdbc or -DQAENV=jdbc to the JAVA_OPTS environment variable. Only the two that I want get loaded, as appropriate. The rest are just never referenced.