Tomcat deployOnStartup Setting

When I deployed the main site for the Guise™ Internet application framework, I wanted to make the setup easy to upgrade. When a new version of the site was ready, I wanted to be able to simply copy the new .war file over the old one and restart Tomcat. But this Tomcat installation is sitting behind Apache and running several virtual hosts, so I had to create distinct Host sections in /usr/local/tomcat/conf/server.xml. In addition, I had to turn off the unpackWARS setting or I would need to delete the automatically-created directory every time I copied an updated .war file. Here was the first attempt (note that this configuration uses a connector to Apache sitting in front of Tomcat):


<Server port="8005" shutdown="SHUTDOWN">
  <Service name="Catalina">
    <Connector port="8009" enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
    <Engine name="Catalina" defaultHost="localhost">
      <Host name="www.example.com" appBase="/var/web/apps"
       unpackWARs="false" autoDeploy="false"
       xmlValidation="false" xmlNamespaceAware="false">
        <Alias>example.com</Alias>
        <Context path="" docBase="www.example.com.war">
          <Parameter name="dataDirectory" value="/var/web/data/www.example.com/"/>
        </Context>
      </Host>
    </Engine>
  </Service>
</Server>

There's a problem with this configuration, though, and it has to do with the distinction between autoDeploy and deployOnStartup introduced in Tomcat 5. I had thought that setting autoDeploy=false would prevent Tomcat from automatically deploying .war files found in the designated appBase, but apparently this setting only prevents Tomcat from automatically deploying new .war files placed in the application base path while Tomcat is running. With the above configuration, Tomcat will deploy www.example.com.war according to the provided Host information, including the given initialization parameter, but then Tomcat will attempt to deploy the same .war file with a default context, as the .war file is located within /var/web/apps.

Sure enough, the Apache Tomcat 5.5 Configuration Reference: Automatic Application Deployment notes that the application may be deployed twice if automatic deployment is used and the specified docBase references a .war file inside the designated appBase. One way to fix this is to move all the .war files outside the application base directory, like this:


<Server port="8005" shutdown="SHUTDOWN">
  <Service name="Catalina">
    <Connector port="8009" enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
    <Engine name="Catalina" defaultHost="localhost">
      <Host name="www.example.com" appBase="/var/web"
       unpackWARs="false" autoDeploy="false"
       xmlValidation="false" xmlNamespaceAware="false">
        <Alias>example.com</Alias>
        <Context path="" docBase="apps/www.example.com.war">
          <Parameter name="dataDirectory" value="/var/web/data/www.example.com/"/>
        </Context>
      </Host>
    </Engine>
  </Service>
</Server>

But that's less than elegant, because the so-named base application directory no longer serves as a base application directory. The deployOnStartup setting seems to be the key, here; setting it to false (it defaults to true) seems to prevent Tomcat from automatically deploying all the .war files in the appBase directory:


<Server port="8005" shutdown="SHUTDOWN">
  <Service name="Catalina">
    <Connector port="8009" enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
    <Engine name="Catalina" defaultHost="localhost">
      <Host name="www.example.com" appBase="/var/web/apps"
       unpackWARs="false" autoDeploy="false" deployOnStartup="false"
       xmlValidation="false" xmlNamespaceAware="false">
        <Alias>example.com</Alias>
        <Context path="" docBase="www.example.com.war">
          <Parameter name="dataDirectory" value="/var/web/data/www.example.com/"/>
        </Context>
      </Host>
    </Engine>
  </Service>
</Server>

More information can be found at the Apache Tomcat 5.5 Configuration Reference: Host Container.