Search code examples
tomcatpropertiestomcat8environment

Tomcat: specify different properties for different webapps


I run a series of separate webapps which need separate configuration but all essentially use the same code, and consequently identical war files. The war file is able to read the path to its configuration file from an environment variable, and I can see how to set an environment variable for an entire Tomcat Context in the context.xml file.

However, I can't see how to run individual webapps in separate contexts; and all the webapps in the same context will see the same value of the environment variable and consequently load config from the same place.

Is there a mechanism to set different environment values for different webapps within a context; If not, is there some other mechanism (outside the WAR file itself) to specify different property values for different webapps, or a way to create a separate context for each webapps?

Finally, if I can move the configuration outside the webapp, is it possible to have several webapps use the same actual WAR file (as they are all identical apart from config,and it would make upgrades much easier if I just had to drop in a single WAR file)?


Solution

  • Edit: Looking at your code (particularly configuration.clj) it appears that you are using system environment variables (which are shared among all web applications). You should use environment entries instead and retrieve them through a call to InitialContext.lookup("java:comp/env/FOO") instead of System.getenv("FOO").

    Technically every application has its own <Context>, which is composed by (cf. Tomcat documentation):

    • the values from $CATALINA_BASE/conf/context.xml,
    • the values from $CATALINA_BASE/conf/<enginename>/<host>/context.xml.default
    • the values from $CATALINA_BASE/conf/<enginename>/<host>/<path>.xml or (if it is missing and deployXML of the <Host> is not false) the entries in META-INF/context.xml of your application.

    Each more specific configuration file can overwrite the attributes of the more general configuration files, while the nested components are added up. Therefore you should probably define:

    • the environment entries specific to each application in $CATALINA_BASE/conf/<enginename>/<host>/<path>.xml,
    • the environment entries common to all applications in $CATALINA_BASE/conf/context.xml.

    Remark: Usually <enginename> is Catalina, while <host> is localhost.

    If you are using the same WAR file you can just place it outside of the document base (let's say /usr/share/my.war) and create a bunch of <path>.xml files in $CATALINA_BASE/conf/<enginename>/<host>:

    <Context docBase="/usr/share/my.war">
        <!--
            environment entries
        -->
    </Context>
    

    The path under which they will be deployed will be inferred from the name of the XML.