mod_cfml wrangling

In a previous post I talked about how Railo’s default install with mod_cfml can cause problems when you have a lot of virtual hosts. This post will deal with some details of various configurations to deal with those problems. I’ll assume an Apache + Linux install for these config examples.

Config file locations

Tomcat config is in /opt/railo/tomcat/conf
Tomcat context files are in /opt/railo/tomcat/conf/Catalina/<hostname>/ROOT.xml, where “hostname” is the hostname from the Tomcat host configuration. Mod_cfml uses the hostname from the URL for this purpose, but you can define it to be anything.
Apache config is in /etc/apache2

1. Explicitly define Tomcat hosts and aliases

The first thing you can do is to explicitly handle most or all of your Tomcat context creation, rather than let mod_cfml do it for you. Because of the way mod_cfml works, it stays completely out of the loop and adds no overhead for explicitly defined contexts.

For each distinct Railo application, add a <Host> element to Tomcat’s server.xml, like so:

<Host name="lotsahosts.me" appBase="webapps">
   <Alias>myalias1.lotsahosts.me<Alias>
   <Alias>myalias2.lotsahosts.me<Alias>
   <Alias>myalias3.lotsahosts.me<Alias>
</Host>

Important: this configuration is in addition to your virtual host setup in your web server.

Then create the context file, which will be called /opt/railo/tomcat/conf/Catalina/lotsahosts.me/ROOT.xml, and should contain:

<?xml version='1.0' encoding='utf-8'?>
<Context docBase="/var/www/myapps/lotsahosts_webroot">
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>

TBH I don’t think the WatchedResource element is needed. It’s just come along for the cut-and-paste ride since forever.

To reiterate, you’ll need Host element and a context file for every distinct Railo application. How do you know when you need a new Host element, as opposed to just adding an Alias? It comes down to what your ColdFusion code is expecting. If it’s OK with handling multiple hostnames, then go ahead and use an alias. Otherwise, add a Host element and context file.

2. Disable the mod_cfml Tomcat valve

After the above config change, mod_cfml will stay out of the picture until your web server sends through a host header that you haven’t explicitly handled. At that point, mod_cfml springs into action and creates the context for you.

This can be a reasonable way to operate if you frequently need to provision new virtual hosts that are all just aliases into the one web app. You can let mod_cfml dynamically create the contexts, but keep the total context count down by periodically sweeping them up into your static configuration (i.e. add an <Alias> element to server xml and then just delete the context folder from conf/Catalina). However, if your new virtual hosts are not just aliases, your context count will unavoidably increase, and you’ll run into mod_cfml’s startup overhead.

So, to disable the mod_cfml Tomcat valve, just comment out these lines in Tomcat’s server.xml:

	<Valve className="mod_cfml.core"
		loggingEnabled="true"
		waitForContext="60"
		maxContexts="200"
		timeBetweenContexts="1"
		/>	

Once you’ve done that (and restarted Railo), any host header that you haven’t explicitly handled will result in a 404 error.

3. Remove the web server’s mod_cfml component

If you’ve read the mod_cfml documentation (which I’d recommend), you’ll know that mod_cfml is actually a matched pair of components, one on the web server side and one on the Tomcat side. The web server component works differently depending on which web server you run. On Apache, it’s a very lightweight component that runs on top of the usual mod_proxy or mod_jk setup and adds some headers to help the Tomcat valve know how to set the docBase for new contexts.

I’m not sure why you’d need or want to remove the web server component, as the startup and memory overheads are all on the Tomcat side. But, for completeness, here’s how to do it for Apache 2.2: simply remove the PerlRequire, PerlHeaderParserHandler, and PerlSetVar directives from /etc/apache2/apache2.conf. Note that on older Apaches those directives might be in httpd.conf.

On IIS, mod_cfml uses the Boncode connector. If you want to remove that, you’ll have to replace it with another connector, but I’m no IIS guru, so I’ll leave it at that.