Viewing By Entry / Main
May 11, 2009
Today I had a short gap between projects so I finally created a multi-web install of Railo on Tomcat. I'm deeply indebted to Jamie Krug for his Railo JAR install tips and tricks blog post which I used as a starting point for my installation process.

Downloading

Start with a clean install of Tomcat. I downloaded 6.0.18 and unzipped it into /Developer/tomcat/. Don't start it up yet.

For Railo, you'll either need the custom JARs ZIP file or the WAR (which is just a ZIP anyway). The latter makes it a little easier to copy'n'paste the XML fragments you need to add to Tomcat's root web.xml file but I'll show them all below for convenience.

Preparation

In the Tomcat folder create a railo/ folder and copy in the contents of the unzipped Railo JARs ZIP file (or from the WEB-INF/lib/ folder of the unzipped Railo WAR file).

In the Tomcat conf/ folder, edit catalina.properties and find the common.loader class path. We're going to add the Railo JARs to the common class path so that every web application can have Railo CFML pages. The new common.loader definition should look like this (all on one line, no spaces):

common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar,
${catalina.home}/railo,${catalina.home}/railo/*.jar
Note: embedding Railo directly in Tomcat like this means that you will end up with a generated WEB-INF/ folder in each webroot, containing some Railo files (about 2MB).

Unless you're going to use the default web applications that come with Tomcat, this is a good time to empty the Tomcat webapps/ folder. You could create a default/ folder in the Tomcat folder and move everything from webapps/ to default/ - this makes it easy to configure the applications again under a new hostname (I'll show this at the end).

Next we must configure the Railo Servlet stuff. In the Tomcat conf/ folder, edit web.xml. This is the master web application configuration for the Tomcat server and any web applications you create will inherit from it.

At the end of the servlet section, just before the servlet-mapping section, add the following:

<servlet>
   <servlet-name>RailoCFMLServlet</servlet-name>
   <description>CFML runtime Engine</description>
   <servlet-class>railo.loader.servlet.CFMLServlet</servlet-class>
   <init-param>
<param-name>configuration</param-name>
<param-value>/WEB-INF/railo</param-value>
<description>Configuration directory</description>
</init-param>   
   <!-- init-param>
<param-name>railo-server-root</param-name>
<param-value>.</param-value>
<description>directory where railo root directory is stored</description>
</init-param -->
   <load-on-startup>1</load-on-startup>
</servlet>   
<servlet>
   <servlet-name>RailoAMFServlet</servlet-name>
   <description>AMF Servlet for flash remoting</description>
   <servlet-class>railo.loader.servlet.AMFServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>   
<servlet>
   <servlet-name>RailoFileServlet</servlet-name>
   <description>File Servlet for simple files</description>
   <servlet-class>railo.loader.servlet.FileServlet</servlet-class>
   <load-on-startup>2</load-on-startup>
</servlet>
Note that I have prefixed these Servlets with Railo so that you can still deploy Railo WAR-based web apps without conflict (chops to Jamie Krug for this - he renamed his Servlets to have GLOBAL in front of their names).

Next, at the end of the servlet-mapping section, just before the filter section, add the following:

<servlet-mapping>
   <servlet-name>RailoCFMLServlet</servlet-name>
   <url-pattern>*.cfm</url-pattern>
</servlet-mapping>
<servlet-mapping>
   <servlet-name>RailoCFMLServlet</servlet-name>
   <url-pattern>*.cfml</url-pattern>
</servlet-mapping>
<servlet-mapping>
   <servlet-name>RailoCFMLServlet</servlet-name>
   <url-pattern>*.cfc</url-pattern>
</servlet-mapping>
<servlet-mapping>
   <servlet-name>RailoAMFServlet</servlet-name>
   <url-pattern>/flashservices/gateway/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
   <!-- could be RailoFileServlet -->
   <servlet-name>default</servlet-name>
   <url-pattern>/</url-pattern>
</servlet-mapping>
Note that I have used the default Tomcat Servlet for serving files, per my recent Quick Tip (so you need to set listings to true in the default Servlet definition at the top of the file if you want directory listings).

Finally, at end of the file, add index.cfm (and index.cfml if you wish) to the list of "welcome files".

If you emptied the webapps/ directory above, create an empty folder called ROOT/ in there so that we'll have at least one web application when we start Tomcat.

Let's get this party started!

We're ready to start Tomcat now. In Terminal, go to the Tomcat bin/ folder and start Tomcat:

sh startup.sh
In a few seconds, you'll be able to browse to http://localhost:8080/ and see an empty directory listing. How exciting! Browse to http://localhost:8080/railo-context/admin.cfm and you should see the Railo entry page for the Server and Web Administrators. Login to each and set an initial password.

At this point, the Server Administrator data is actually stored in {tomcat}/railo/railo-server/ and the Web Administrator data is stored in {tomcat}/webapps/ROOT/WEB-INF/railo/.

Settings in the Server Administrator cascade down into all the Web Administrators associated with the Tomcat server - and the Server Administrator can determine what features can be changed in those Web Administrators.

You can stop Tomcat now (by switching to the org.apache.catalina.startup.Bootstrap application and selecting Quit from the menu). The shutdown.sh script does not reliably shut Tomcat down for a number of web applications.

Adding websites

The first step is always to add a new domain name for each site to your local hosts file so all those domains resolve to 127.0.0.1.

Let's assume you have web1.local and web2.local defined there. Let's also assume that the desired webroots for these sites are ~/Documents/sites/web1.local/www/ and ~/Documents/sites/web2.local/www/.

In the Tomcat conf/ folder, edit server.xml and find the Host definition for localhost (around line 126). You can add your new host definitions below that, as follows:

<Host name="web1.local" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">

      <Context path="" docBase="/Users/yourname/Documents/sites/web1.local/www"/>
</Host>
<Host name="web2.local" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">

      <Context path="" docBase="/Users/yourname/Documents/sites/web2.local/www"/>
</Host>
Now start Tomcat again and you'll see a WEB-INF/ folder created inside each of those two sites' www/ folders.

Browse to http://web1.local/railo-context/admin/web.cfm, set a new password and login. This is the Web Administrator for the web1.local website. Similarly, http://web2.local/railo-context/admin/web.cfm is the Web Administrator for the web2.local website.

The Server Administrator accessible from http://web1.local/railo-context/admin/server.cfm is the same, shared Server Administrator under localhost or web2.local.

You now have a shared hosting environment on your local computer with each 'account' having its own full administrator console!

Those default Tomcat applications

Remember we moved those default applications (docs, examples, host-manager, manager, ROOT)? You can easily make them accessible again as a new website. Add tomcat.examples to your hosts file (resolving to 127.0.0.1) and then add the following to Tomcat's server.xml file:

<Host name="tomcat.examples" appBase="default"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">

</Host>
Note the appBase is a different top-level folder in Tomcat.

When you next restart Tomcat, you'll see Railo's files added to the WEB-INF/ in each of those five web applications but you'll be able to browse to http://tomcat.examples/docs for example (and view the Tomcat documentation).

Comments

Iam on windows and installation went well like you explained. But few issues I face now are:

My entry on server.xml are <Host name="web1.local" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context path="" docBase="c:\inetpub\wwwroot\web1.local"/> </Host> <Host name="web2.local" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context path="" docBase="c:\inetpub\wwwroot\web2.local"/> </Host>

I can see WEB-INF folder with subfolders like flex, railo and an .htaccess file under these two website folder. But once I access the website http://web1.local:8080/railo-context/admin/server.cfm Iam getting error says below

HTTP Status 404 -

type Status report

message

description The requested resource () is not available. Apache Tomcat/6.0.18

. Please note that IIS is running with CF8 on port 80 and thats the reason I called the railo webs using 8080 ports.

Please advice.


Ace guide Sean, cheers. Am I correct in thinking you'd then just use a per-virtual host mod_proxy if you needed it to sit behind an existing Apache ?


Hey, thanks, Sean! I'm also documenting my production VPS (Ubuntu Linux) configuration here: http://docs.google.com/Doc?docid=dchcmx7_13dbm8xmgn&hl=en

It's basically just as you've outlined things above, but I have the file system locked down a bit better and auto-run the Tomcat service as an unprivileged user. The is much more secure, but you need to be careful about providing the tomcat user permissions in any directories where Railo needs to write to the file system (e.g., WEB-INF under each Web root, by default). For development environments, it's of course easiest to keep things in a home folder, running as your main/regular user so there are no permissions to worry about.

I've also implemented your tips for AJP proxying from Apache and hiding/protecting the Railo Admin URLs.


for this line "In the Tomcat conf/ folder, edit catalina.out and find the common.loader class path." - should this be catalina.properties?


@Ryan, good catch. Fixed.

@Jamie, yes, good points re: security - thanx for the link to your doc!

@Tom, yes, or a wildcard mod_proxy if you don't need per-virtual host specific Apache configuration (i.e., and let Tomcat handle everything).

@Shimju, a couple of questions: can you hit localhost:8080/railo-context/admin.cfm ? can you put a test.cfm file in web1.local and hit web1.local:8080/test.cfm ? That will show whether it's a problem with your basic Tomcat / Railo setup or just the Host/Context.

Remember, your best bet for support is either:

a) a paid support program from Railo -www.getrailo.com/index.cfm/services/support/

b) free support from the community - www.getrailo.org/index.cfm/community/mailing-list/


Wow. Thanks Jamie and Sean. This is really interesting stuff. I think I'll try out the combo of Ubuntu, Apache, Tomcat, and Railo...


@Sean,

Now after system restart, everything seems working perfectly. Both web1.local:8080/ and web2.local:8080/ are working fine including railo context. I can able to hit localhost:8080/railo-context/admin.cfm earlier also. Thanks a lot Sean for this nice article. More I play on Railo, more it seems interesting. I bet Railo can bring more opensource applications into our CFML world.


@Sean, Tomcat doesn't do URL rewriting, so I think of replacing it with RESIN. Can we able to a create a multi-web install of Railo on RESIN?


@Shimju, yes, this is possible with Resin as well. I'm not yet familiar enough with Resin to post instructions but I'll make sure we post them soon (ultimately, all these install how-to posts will become part of the core documentation on the Railo site).


@Shimju, It is very easy to add URL rewriting to Tomcat, see http://tuckey.org/urlrewrite/


Thanks Brian for that URL.


Just a note that for Railo 3.1 the correct servlet and servlet mappings for AMF support are

<servlet> <servlet-name>RailoAMFServlet</servlet-name> <description>AMF servlet for flash remoting</description> <servlet-class>railo.loader.servlet.AMFServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <!-- MessageBroker Servlet --> <servlet> <servlet-name>RailoMessageBrokerServlet</servlet-name> <display-name>RailoMessageBrokerServlet</display-name> <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class> <init-param> <param-name>services.configuration.file</param-name> <param-value>/WEB-INF/flex/services-config.xml</param-value> </init-param> </servlet>

and <servlet-mapping> <servlet-name>RailoAMFServlet</servlet-name> <url-pattern>/openamf/gateway/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>RailoMessageBrokerServlet</servlet-name> <url-pattern>/flex2gateway/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>RailoMessageBrokerServlet</servlet-name> <url-pattern>/flashservices/gateway/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>RailoMessageBrokerServlet</servlet-name> <url-pattern>/messagebroker/*</url-pattern> </servlet-mapping>


Thanks Sean, simply brilliant!

Followed your blog and flawlessly deployed two railo apps side-by-side.

One additional note:

I added the MessageBrokerServlet definitions per: http://groups.google.com/group/railo/browse_thread/thread/1681fc25f23b3de3/d60b66a7ee9e7af7?lnk=gst&q=blazeds#d60b66a7ee9e7af7

Only I followed your lead and prefixed them as RailoMessageBrokerServlet and both apps now server data to flex via blazeds.

Thanks Again.


One minor point is that this won't work for Flex Remoting, as you need to make a unique RailoMessageBrokerServlet for each web root.

Full details are in https://jira.jboss.org/jira/browse/RAILO-400 including the per-webroot web.xml


@Tom, thanx for that detail - I haven't done much with Flex Remoting on Railo yet.


@Tom, Right! I realized this later. I think only the servletId needs to be unique, however I made a small web-app declaration in each WEB-INF/web.xml file per railo instance i needed blazeds for.

The declaration is basically the same only for each with only a simple servlet and servlet-mapping declared in each web.xml

I think only the ServletId needs to be unique, but it doesn't hurt to namespace all of them.


Thanks Sean, both this tutorial and Jamie's one have been incredibly helpful with getting my noob head around Tomcat and Railo. One problem that I hit with Tomcat6 is that I kept getting a org.apache.tomcat.util.digester.Digester fatalError showing up in my logs every time I added the railo directories to my server classpath. The issue turns out to be an incorrect encoding in the tomcat-users.xml file in /conf (tomcat bug: http://mail-archives.apache.org/mod_mbox/tomcat-dev/200903.mbox/%3Cbug-46908-78@https.issues.apache.org/bugzilla/%3E). Anyway, changing that to ISO-8859-1 solved that and Tomcat is now happily serving CFM's! Just in case that's useful for others.


AWESOME! I can't tell you how many countless hours i've been trying to get this set up on my Slackware box. My server guys have set up tomcat instances under home/resources/tc_1 , tc_2, etc as means to balance the load for some sites that require more attention than others. Meanwhile, all the tomcat instances reference back to a generic tomcat/lib which is the catalina_home.

Sorry for the introduction but i felt it necessary if i'm to figure out my issue as follows:

I followed the above perfectly and all seems to finally work. However, i have copies of web-inf in the following directories: home/resources/tc_#/conf/ home/resources/tc_#/webapps/ and where they should be: mydir/webroot/

My Catalina.Props file contains: common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar,/home/resources/tc_3/railo,/home/resources/tc_3/railo/*.jar

My Server.xml Vhost: <Host name="sbiwd5.kattare.com" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false" appBase="webapps"> <Context path="" docBase="/home/sites/spectrafluidics2_com" /> <Alias>www.sbiwd5.kattare.com</Alias> </Host>

Again, thanks so much for a great tutorial! Have any suggestions for this problem? I'm also going to try Jamie Krug's SES for Railo, Tomcat, and Mura CMS. Any suggestions on that one?

Thanks, David


Just an FYI, not sure why I had to do this, but wanted to document it here for future reference. I followed the entire setup step by step, but at the end the localhost:8080 and the localhost:8080/railo-context/admin.cfm did not load. After I checked the log files (thanks jamie krug) it lead me to the solution for the error that i recieved in my tomcat-users.xml file. The original line that was causing the problem was <?xml version="1.0" encoding="cp1252"?> and the fixed line <?xml version="1.0" encoding="ISO-8859-1"?>

I'm not sure if i should change this to UTF-8, but i looked at web.xml and that's what it had, so i wanted to keep them consistent. Is there a difference and should it be UTF-8? That would be good to know.

Thanks,

Hatem


@Hatem, I've a few people run into that. No idea why some Tomcat installs have that broken encoding (unfortunately nothing we at Railo can do about it - other than add a note about it to any Railo-on-Tomcat installation guide).


Hi Sean great post I have used this to setup my tomcat/railo installation, but have one question that i hope you or one of the guys here can help me with, I have multiple apps in the webapps directory of tomcat and when I start tomcat they all get the web-inf add on for railo, I was wondering if there was any way I could exempt these directories from this?


@Mark, my understanding is that once you integrate Railo's JAR files into Tomcat, it treats all web applications equally and there's no way to turn it off for specific web applications. I've not seen anyone post a way to do that - and it would certainly be useful in some situations.


@Mark, @Sean, I know Gert posted an interesting theory on the Railo Google list recently. I think the basic idea is to place all Railo jars *except railo.jar* in a Tomcat classpath. Then, just create a WEB-INF with the railo.jar for each app that requires Railo. Sounds good in theory anyway, but I don't have time to tinker right now :) I'd also imagine that this would mean separate Railo Server Admins for each app, which may not be desirable, but you'd basically get the equivalent of full-blown Railo WARs for each app while sharing most the lib and conserving server resources.


@Jamie, interesting. That would remove the main benefit (for me) of auto-deployment tho' and the centralized server administration that I rely on.


Hi Sean have a multi-web configuration running fine but have noticved something odd today I have now lost the ability to view debug information when enabled from the aministrator any ideas?


A detail, but as mentioned in your previous guide:

http://corfield.org/blog/index.cfm/do/blog.entry/entry/Railo_for_Dummies_Part_III

you need to chmod to make the shell scripts executable:

chmod +x *.sh


Hi Sean,

Thanks for a great tutorial.

I had to include the oracle jar but didn't discover this until after following your instructions.

When I put this into {catalina.home}/railo it doesn't seem to be accessible by my subsites.

Is there any way to "refresh" all the jars those ones have access to?

Best regards, Andrew.


@Andrew, if you want the Oracle driver accessible by all Tomcat sites, put it in {catalina.home}/lib/ (and restart Tomcat).


Using the RAILO 3.1.2.001 war on Tomcat/6.0.20 I was seeing this Warning on startup:

javax.servlet.ServletException: static path [/WEB-INF/railo/] for servlet init param [railo-web-directory] is not allowed, path must use a web-context specific placeholder.

Using the context variable like Resin app-default.xml uses Seems to fix the warning:

<param-value>{web-root-directory}/WEB-INF/railo</param-value>


@Kevin... thanks for update! that totally helped get rid of that error for me too!


What is a good place for posing questions to the Railo Community. I was load-testing a setup similar to the one described here ... I am sending in 10 concurrent requests for 100 iterations. I can see that railo handles 1 request at a time (others wait till previous request is finished), while Adobe CF-8 is handling multiple request (5 users wait while 5 are finished).

However, each individial request is faster in Railo than CF-8.

The application being tested is a webservice and is exactly the same.

I would like someone to ponder over this with me :)


@Anang, the Railo mailing list is the place for questions:

http://www.getrailo.org/index.cfm/community/


Hey Sean, I already have Apache on the server so tomcat wont be able to listen on port 80, do you have any details on how to use Apache instead of tomcat as the webserver.


@snake, sure, I cover that in the Railo for Dummies blog post series (March 2009).


Post Your Comments
Name:
Email Address:
Comments
*** Please note that all comments require moderation so it may be some time before your comment posts to this blog! ***
Remember My Information:
 



Hosting provided by