An Architect's View

CFML, Clojure, Software Design, Frameworks and more...

An Architect's View

Railo for Dummies Part IV

March 27, 2009 ·

After getting a very basic Railo+Tomcat setup running, now we're going to make it more robust and more 'production-ready' (you'll want to do more than I'm going to show so I'd refer you to the extensive Tomcat documentation for deeper configuration). I'm just going to show how to get Tomcat integrated with Apache in a couple of ways so you can run a 'real' website on it.I'm going to assume you've followed the instructions in Part III and have an interim Railo+Tomcat installation already running. Preparing Tomcat If Tomcat is running, shut it down (by quitting the org.apache.catalina.startup.Bootstrap application). First, we want move the Tomcat folder to a more permanent home. Using the Finder, I dragged apache-tomcat-6.0.18 to my /Developer folder but you can put it in your home directory or wherever else you want. Then I renamed it to tomcat so that the directory path is easier to type. Second, we want to make Railo the 'root' web application so that it no longer needs the /railo prefix on its URLs. In the Finder, I renamed the ROOT folder, under webapps, welcome (you could - and probably should - remove it altogether on production). Then I renamed railo to ROOT. Then we'll start Tomcat. I used the following shell command:
(that expands to /Developer/tomcat/bin/ You could just as easily double-click the Tomcat start script in the bin folder if you followed by tip about renaming in the last post. At this point, we can browse to http://localhost:8080/ and see the Railo test page. I had to force my browser to refresh since it had cached the previous Tomcat welcome page. If you renamed the old ROOT folder to welcome, as I did, you can still reach it on http://localhost:8080/welcome/. Enabling Tomcat Users (optional) If you want to look at the Tomcat Manager console, you need to do one more piece of configuration on Tomcat: adding a Tomcat user. In the Finder, navigate to the conf folder under Tomcat and open tomcat-users.xml with your favorite text editor (I use TextMate because it supports SVN, CFML and a number of other languages but you can easily use the built-in TextEdit application). In the <tomcat-users> section, add a user definition like this:
<user username="someuser" password="secret" roles="admin,manager"/>
Pick whatever username and password you want - make it nice and secure! Restart Tomcat to pick up the change (I thought it might pick up the change automatically but it didn't seem to notice when I saved the file). Now you can browse to http://localhost:8080/manager/html and you'll be challenged for the username and password you defined above. When you've logged in, you'll see a list of the web applications that are active on Tomcat, along with the number of active sessions and basic controls to stop / start / reload / undeploy the applications. Warning: undeploying an application removes the entire directory structure from webapps! As you'll see, in addition to the Railo web application (now at /), there are web applications for documentation (/docs), examples (/examples) and a couple of 'manager' applications. In production, you would want to remove anything you don't need. Since you can 'manage' Tomcat by editing XML files, you could remove everything except the ROOT (Railo) application. Two main issues remain at this point:
  • The web root is webapps/ROOT/ under the Tomcat install
  • We are using port 8080 and not routing through Apache on port 80
Changing the Tomcat web root By default, Tomcat assumes the web root for each application is a folder under webapps. Also by default, the URL for each web application begins with a 'context root' that is the name of that directory (with the empty context - / - for the ROOT folder). This behavior is controlled by Tomcat's conf/server.xml file. Open it up in your favorite text editor and go to the bottom of the file. You'll see a <Host..> section that defines the behavior for the default virtual host. You can add <Context..> tags inside this section to override the default 'context root' behavior for web applications. For my setup, I want the web root to be /Users/scorfield/Sites for the empty context so that I can browse a local copy of my site. I added:
<Context path="" docBase="/Users/scorfield/Sites"/>
Then I copied the WEB-INF folder from Tomcat's webapps/ROOT folder to my local site and restarted Tomcat. WEB-INF contains the full definition of a Java web application so you can easily clone applications just by copying them. Now, when I browse to http://localhost:8080/ I get the local copy of my website instead of the default Railo site under Tomcat! As you might imagine from reading the comments around the <Host..> tag, you can have multiple hosts defined, each with a different set of applications, each having their own 'context root' and their own web root. Read the Tomcat 6 documentation for more details of what other configurations are possible. Configuring Apache with Tomcat In most blog posts, this is always the hardest part to follow. Almost everyone shows how to configure mod_jk which, whilst fairly standard, is a lot of work. For example, see Marko Tomic's post on the Lynch Consulting blog which walks you through building mod_jk from source in order to get Apache up and running. That's far too much work for my taste and there is a much simpler solution, in my opinion. What a lot of people forget is that Tomcat is a very robust, high performance web server in its own right. With JRun (under ColdFusion), you usually want have Apache handle static content and JRun handle the requests for CFML pages and that's why you would use the JRun connector (which is what ColdFusion installs by default when you tell it to connect to a web server). You could simply tell Tomcat to use port 80 and leave Apache out of the picture altogether. Just change the port= attribute from 8080 to 80 on the <Connector..> tag for the Catalina service in Tomcat's conf/server.xml file. However, most systems run an existing web server on port 80 and you probably don't want to interfere with that - and instead just connect it to Tomcat. The easiest way to connect Apache to Tomcat is to proxy requests. This way you have control over which URLs are passed to Tomcat and can easily leverage all the other useful Apache modules. Here's an example of an Apache virtual host for (an entry in my /etc/hosts file that points to for testing my site locally):
<VirtualHost *:80>

DocumentRoot /Users/scorfield/Sites

ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
This maps any request to Apache for to Tomcat using the empty context root, which we already mapped to the same document root above. I can use additional ProxyPass directives to exclude mapping certain requests. For example, I could exclude my images directory (and let Apache serve that instead of Tomcat) by adding this as the first ProxyPass directive:
ProxyPass /images !
I added the virtual host above to /etc/apache2/extra/proxy.conf and then edited /etc/apache2/httpd.conf to add the following immediately after the NameVirtualHost *:80 directive:
Include /private/etc/apache2/extra/proxy.conf
I prefer to keep my httpd.conf file as clean as possible and use include files for virtual hosts and other customization. You can restart Apache from the command line:
sudo apachectl restart
It will usually prompt you for your password. At this point you have Apache+Tomcat+Railo configured and you should be able to set up as many local virtual hosts as you want, each with its own web root and a local configuration of Railo. In future posts, we'll look at additional ways to configure Apache, Tomcat and Railo. I'll also take a stab at configuring things with IIS at some point.

Tags: apache · coldfusion · osx · railo

20 responses

  • 1 Ryan McIlmoyl // Mar 27, 2009 at 8:25 PM

    Sean, just found this article about installing railo in iis7. I don't have an iis7 instance I can test this on, but thought you might be interested before your attempt at a Windows install (this is Resin though, not Tomcat)
  • 2 Barney Boisvert // Mar 27, 2009 at 8:33 PM

    If you're on Apache 2.2, using AJP instead of HTTP for your proxying will give some nice features. In particular, you'll get the Apache hostname instead of the Tomcat hostname ( and localhost respectively) in your ServletRequest, and you'll be aware of the presence of SSL if you're using Apache to do that instead of Tomcat.
  • 3 Sean Corfield // Mar 27, 2009 at 10:10 PM

    Paul Kukiel asked me about determining the remote IP address of the request. The answer is that mod_proxy adds X-Forwarded-For so you can retrieve that by using CGI.HTTP_X_FORWARDED_FOR in CFML to get the &quot;original&quot; remote IP address. Note that CGI.REMOTE_ADDR will be because the request (to Tomcat) is made from the Apache instance on the same server.

    @Barney, CGI.SERVER_NAME gives me with mod_proxy configured as described but, yes, AJP provides more options. The docs say &quot;This is used for cases where you wish to invisibly integrate Tomcat 6 into an existing (or new) Apache installation, and you want Apache to handle the static content contained in the web application, and/or utilize Apache's SSL processing.&quot;
  • 4 Sean Corfield // Mar 27, 2009 at 10:18 PM

    I just tried AJP and it passes through the correct REMOTE_ADDR and REMOTE_HOST values (and does not set HTTP_X_FORWARDED_FOR) so that probably is a better way to set things up.

    For me, this was as simple as replacing http://localhost:8080/ with ajp://localhost:8009/ in the ProxyPass and ProxyPassReverse directives (the Connector for port 8009 is already defined by default in Tomcat).
  • 5 Paul Kukiel // Mar 28, 2009 at 5:47 AM

    Thanks for the answer Sean I use a reverse proxy to serve up content from several different internal machines from a single external IP and while I'm not using the remote address someone asked me once about this and I thought it wasn't possible. The trick for me was the &lt;cfdump var=&quot;#cgi#&quot; /&gt; won't show HTTP_X_FORWARDED_FOR but &lt;cfdump car=&quot;#cgi.HTTP_X_FORWARDED_FOR#&quot; /&gt; does. As for ajp that seams like a great solution to proxy to tomcat so thanks for that Barney.

    BTW using: &quot;ProxyPreserveHost on&quot; in the &lt;Vhost/&gt; block sends the host header name through the proxy to tomcat/other webserver rather then the hostname of the apache machine.
  • 6 Charlie // Mar 29, 2009 at 9:35 AM

    Where do I've to insert the VirtualHost-Stuff?

    I've tried it in tomcats server.xml --&gt; error was that after Virtualhost there must be &gt; or /&gt;

    Then tried it in httpd.conf --&gt; error was that ProxyRequests is an invalid command
  • 7 Sean Corfield // Mar 29, 2009 at 11:13 AM

    @Charlie, the post says to put that VirtualHost definition in a separate file and add the Include directive in the main httpd.conf file.
  • 8 Charlie // Mar 29, 2009 at 10:24 PM

    @Sean, thx a lot, sorry for this, but I think I shouldn't work so many hours at weekends ;-)

    I've also to mention, that one has also to enable these modules for apache e.g. in this case all of the proxy-Modules.

  • 9 Sean Corfield // Mar 29, 2009 at 11:12 PM

    @Charlie, mod_proxy has been enabled by default on every Apache install I can remember working on. Sometimes mod_rewrite is not tho'...
  • 10 Matt Woodward // Mar 31, 2009 at 2:47 PM

    Just having time to read through these--fresh installs of Apache definitely do NOT have mod_proxy enabled by default, at least on Windows (sigh, yes I'll be writing up a blog post on how to do all this stuff on Windows), and Linux. Might be a Mac thing if you didn't have to enable it.

    Also, key to the security of all this is making SURE that ProxyRequests is set to Off. Open proxy servers are bad news for you and the tubes as a whole. :-)
  • 11 Sean Corfield // Mar 31, 2009 at 3:30 PM

    @Matt, the Apache docs say:

    Default:   ProxyRequests Off
  • 12 Matt Woodward // Mar 31, 2009 at 4:31 PM

    Sure, just think it bears repeating since if someone turns that on (and the name is a bit misleading IMO) it has very grave consequences.
  • 13 Tom Jones // Apr 6, 2009 at 12:57 PM

    So when I copied the WEB-INF folder from Tomcat's webapps/ROOT folder to my local site and restarted Tomcat. I copied the index.cfm from the railo war file and placed it in my local site. When I tried to go to it the cfdump info does not show, and I'm unable to get to the admin site.

    What did I do wrong?
  • 14 Sean Corfield // Apr 6, 2009 at 1:00 PM

    @Tom, sounds like you missed a step somewhere but it's hard to tell where. Did you add the Context correctly specifying the new docBase?
  • 15 John Barbic // Apr 25, 2009 at 4:31 PM


    First, thanks for the tutorial. One thing I got lost on was setting up datasources in the railo admin. It took a while, but something like this worked, which makes sense: http://localhost:8080/railo-context/admin/web.cfm?action=services.datasource

    But I'm keen to learn how you might set things up yourself so that you have a better way to access the railo admin. I definitely got confused by the web vs server admins, but I can see how one might chose to set this up a number of different ways. In that light, I love to read more on how you're set up to run multiple sites, and administer railo either at the server or site level like that.
  • 16 Sean Corfield // Apr 25, 2009 at 6:21 PM

    @John, I plan to set up a multi-web Tomcat install soon and document that in a series of blog posts.
  • 17 Terrence Tyson // Nov 23, 2011 at 10:20 PM


    Great post! I've been reading your blog and have learned a lot about Coldbox in a couple of your webinars.

    I am using Mac OSX Snow Leopard and I downloaded Railo 3.3 which installed Tomcat 6.0.24, which works well. But I'm having an issue with URL rewriting in Coldbox. The dashboard opens fine, and my home page in Coldbox opens fine, but the SES based links do not work - I get a 404 error. I followed the instructions on this post and in Part III but I get the same result. I upgraded from Tomcat 6 and Railo 3.2 and never got it to work.

    Could you or anyone reading this blog shed some light on this?

    Thank you.
  • 18 Sean Corfield // Nov 24, 2011 at 3:31 PM

    @Terrence, did you remember to add a servlet-mapping for /index.cfm/* in web.xml?
  • 19 Terrence Tyson // Nov 24, 2011 at 10:15 PM

    @Sean, yes, here is the mapping in {CATALINA_HOME}/conf/web.xml:


    This was installed by default along with *.cfm, *.cfml, *.cfc, and /flashservices/gateway/*.

    These are not included in the WEB-INF directory in my webroot. Should these mappings be moved or copied there also?
  • 20 Sean Corfield // Nov 27, 2011 at 5:55 PM

    @Terrence, I believe those mappings need to be in WEB-INF/web.xml