Viewing Category: Open BlueDragon  [clear category selection]

Painlessly Updating Open BlueDragon

I recently wrote a modest shell script to make updating an installation of Open BlueDragon less cumbersome. I reported an issue with a nightly build, and I wanted to be able to switch between build versions reliably and quickly. The script, available as openbluedragon-nightly-updater.sh, will download and archive the nightly build and then deploy to web application server configured. My development environment is Apache Tomcat on Mac OS X 10.5/10.6. I create a directory in $HOME called Servers into which I download tarball distributions of Tomcat. I then create a symbolic link to the current version as ~/Servers/Tomcat. I use the ROOT context for simplicity. I keep old nightly builds in my ~/Downloads directory. Therefore, the configuration in the update script looks like this:

NIGHTLY="OpenBlueDragon-Nightly-`date +%Y-%m-%d`.zip" SERVER="$HOME/Servers/Tomcat" DEPLOY="$SERVER/webapps" CONTEXT="ROOT" URL="http://www.openbluedragon.org/download/nightly/openbd.war" ARCHIVE="$HOME/Downloads/$NIGHTLY"

The script has two options: (-m) minimal or full update, and (-f) local file or remote download. With the minimal update, it just replaces the $DEPLOY/$CONTEXT/WEB-INF/lib/OpenBlueDragon.jar file. The full update replaces all of the Open BlueDragon JAR files, as well as the administration application and manual. It does not, however delete the existing Open BlueDragon configuration in $DEPLOY/$CONTEXT/WEB-INF/bluedragon. This is important to me because I don't want to lose the current settings for datasources, mail, debugging, and whatnot. I also want to keep all the symbolic links to my CFML applications in $DEPLOY/$CONTEXT in tact.

While working on a problem today, I wanted to verify that the issue wasn't introduced with last night's build. I just ran the following commands to revert to last week's build:

~/Servers/Tomcat/bin/catalina.sh stop ~/Workspace/admin/coldfusion/openbluedragon-nightly-updater.sh -m -f \     ~/Downloads/OpenBlueDragon-Nightly-2010-06-12.zip ~/Servers/Tomcat/bin/catalina.sh start

In less time than it takes to get another Diet Coke, the installation of Open BlueDragon was running an arbitrary version. It turned out that the issue I was troubleshooting had nothing to do with Open BlueDragon -- it was an error in my MXUnit test case. To get running again on the latest version, I ran the script without any arguments.

Jetty: Follow Symlinks

If you use the Open BlueDragon Ready2Run bundle, you may have encountered an issue where Jetty wouldn't follow symbolic links to static file resources (images, scripts, whatnot). In the console, it will print something like WARN: Aliased resource: file:/Users/joseph/Applications/OpenBlueDragon/webapps/openbd/app/images/foo.png==file:/Users/joseph/Projects/app/images/foo.png. The simple way to have Jetty serve the file by following the link is to add an aliases parameter to the default servlet section of ./etc/webdefault.xml file:

<servlet> <servlet-name>default</servlet-name> <servlet-class>org.mortbay.jetty.servlet.DefaultServlet</servlet-class> ... <init-param> <param-name>aliases</param-name> <param-value>true</param-value> </init-param> ... </servlet>

When restarting with the modified XML file, it works like a champ.

Configuring a Production Open BlueDragon Server

I've just finished building up a couple production servers to host web applications. The servers are Xen guests on an AMD Quad-Core Opteron x86_64 host. The VPS template is a minimal installation of CentOS, to which I added packages as needed. The release of Sun Java 1.6u12 came out just as I was writing this, so these instructions will need to get updated slightly when JPackage has a new RPM (more on that later). Both Matt Woodward and Dave Shuck recently wrote about configuring CFML engines with Tomcat. The installation I'll describe is somewhat similar.

  • CentOS 5.2
  • Tomcat 5.5.23 (tomcat5-5.5.23-0jpp.7.el5_2.1)
  • Apache 2.2 (httpd-2.2.3-11.el5_2.centos.4)
  • Sun Java 1.6u11 (java-1.6.0-sun-1.6.0.11-1jpp)
  • Sun JavaMail 1.4.1
  • Open BlueDragon 1.0.1

The installation of packages using yum is a snap, however there was an issue with the architecture detection. There is a simple workaround, to hard-code i386 as the basearch:

sed -i -r 's/\$basearch/i386/g' /etc/yum.repos.d/CentOS-Base.repo

The procedure is to install jpackage-utils, then download and repackage the Sun Java SE Development Kit 6 (jdk 1.6) using the JPackage Project non-free nosrc RPM. I install some, but not all of the, resulting RPMs:

yum --nogpgcheck localinstall java-1.6.0-sun-1.6.0.11-1jpp.i586.rpm java-1.6.0-sun-devel-* java-1.6.0-sun-fonts-*

The CentOS Wiki has a thorough article on installing Java on CentOS. I've considered using OpenJDK, but I don't know what sort of compatibility issues that would raise.

The Tomcat server starts up just fine with GNU's version of the Java runtime (libgcj and java-1.4.2-gcj-compat). However, using the GNU version of JavaMail (classpathx-mail) instead of Sun JavaMail, the following chunk of CFML will fail with a javax.mail.NoSuchProviderException exception from within the Open BlueDragon web application:

<cfscript> server = "localhost"; port = 25; username = ""; password = ""; mailSession = createObject("java", "javax.mail.Session").getDefaultInstance(createObject("java", "java.util.Properties").init()); transport = mailSession.getTransport("smtp"); transport.connect(server, JavaCast("int", port), username, password); transport.close(); </cfscript>

Open BlueDragon does include include the correct Jar, but the JVM that Tomcat configures loads the system version first. Rather that muck about with the classpaths, I downloaded the current version of JavaMail, extracted mail.jar, and created alternatives link:

unzip -j -d /tmp javamail-1_4_1.zip javamail-1.4.1/mail.jar mv /tmp/mail.jar /usr/share/java/javamail-1.4.1.jar alternatives --install /usr/share/java/javamail.jar javamail /usr/share/java/javamail-1.4.1.jar 5000 alternatives --auto javamail file /var/lib/tomcat5/common/lib/\[javamail\].jar

Tomcat installs a set of symlinks to /usr/share/tomcat5. Configuration files are placed in /etc/tomcat5. For this installation, I use a stripped-down version of server.xml that provides web application hosting on a per-user basis.

<Server port="8005" shutdown="SHUTDOWN"> <GlobalNamingResources /> <Service name="Catalina"> <Connector port="8080" address="127.0.0.1" protocol="HTTP/1.1" /> <Connector port="8009" address="127.0.0.1" protocol="AJP/1.3" /> <Engine name="Catalina" defaultHost="localhost"> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" debug="0" /> <Host name="localhost-username" appBase="/home/username/webapps" unpackWARs="false" autoDeploy="false" debug="1"> <Context path="" docBase="openbd" allowLinking="true" caseSensitive="true" swallowOutput="true" /> </Host> </Engine> </Service> </Server>

The standard Tomcat configuration has a single Host within an Engine named Catalina. I've added a second Host that is specific to a system user username, which allows each user on the system to manage their own deployed web applications and choose their own root Context. Installing Open BlueDragon as the default web application simplifies the Apache HTTP configuration.

The username user has an Apache HTTP configuration file in /etc/httpd/conf.d/username.conf with mod_rewrite rules to proxy all requests for CFML files to the Tomcat HTTP Connector. I had intended to use the AJP Connector with mod_proxy_ajp, but there is a problem with the the proxy request not specifying the proper hostname. There might be a solution to that issue, but I haven't found it yet. The plain mod_proxy_http module works properly in the following configuration:

<VirtualHost *:80> DocumentRoot /home/username/websites/sitename ... RewriteCond %{SCRIPT_FILENAME} \.cfm$ RewriteRule ^/(.*)$ http://localhost-username:8080/$1 [P] </VirtualHost>

The rest of the Apache HTTP configuration handles web requests for flat files, served from ~/websites/sitename. The CFML files can be placed in ~/webapps/openbd, however an easier deployment is to place everything in ~/websites/sitename (like you would with a typical ColdFusion server). Symbolic links can be added for directories containing CFML. Consider the following:

cd ~/webapps/openbd ln -s ../../websites/sitename/MachII MachII

It would probably be a good idea to set the Open BlueDragon root mapping appropriately. There are a few issues with file ownership and permissions that I didn't address above. I've added username to the /etc/sudoers file, granting that user limited access.

A Fresh MachBlog

This is a brand new installation of MachBlog. :) I checked out /branches/1.1 and made several tweaks to tune it to my installation. Setting up the application server using Apache, Tomcat, and Open BlueDragon was a bit of a trick. After quite a bit of experimentation, I found a solution that I'm happy with.

The server is a Vivio Linux VPS running CentOS 4.7 and Apache 2.0. Unfortunately, the Extra Packages for Enterprise Linux 4 (EPEL) repository from the Fedora Project don't have a current OpenJDK. I downloaded Java JDK 1.6 directly from Sun. This older version of Apache also doesn't come with the mod_proxy_ajp module. I considered mod_jk, but figured that a plain ol' HTTP proxy would be fine. Apache is configured to read static files from a regular user's home directory, but proxy the CFML requests. The result of the proxy request is modified with the ProxyPassReverse directive so that response headers don't use the localhost:8080 server and port.

<VirtualHost *:80> DocumentRoot /home/user/webroot RewriteCond %{SCRIPT_FILENAME} \.cfm$ RewriteRule /(.*)$ http://localhost:8080/$1 [P] ProxyPassReverse / http://localhost:8080/ </VirtualHost>

Tomcat is configured to run by the ordinary user, rather than as a system service. Therefore, all the Tomcat and Open BlueDragon files are within the user's home directory, and owned by that user, which simplifies file permissions when the application server needs to write uploaded files. Any changes to this user's Tomcat or Open BlueDragon installation, including updates and crashes, aren't system-wide. The Tomcat root is /home/user/server/tomcat. All of the sample web applications have been removed from $TOMCAT/webapps. There is a host context file $TOMCAT/conf/Catalina/localhost/ROOT.xml that sets the docBase attribute to /home/user/server/openbluedragon.

I checked out the source for Open BlueDragon yesterday and built the WAR file to deploy manually. In this hosting configuration, I must add symbolic links for directories in $OPENBD (/home/user/server/openbluedragon) to real directories in $WEBROOT (/home/user/webroot), such as $OPENBD/MachII to $WEBROOT/MachII. There aren't many directories in the root, so it isn't much of an issue.

Note: Don't forget to add the JavaMail jar to $OPENBD/WEB-INF/lib. Again. :)

The following is an oversimplified, and perhaps quite useless, diagram of this hosting setup. I'm looking for a term for this arrangement. Possibly Ordinary User Tomcat and Open BlueDragon Installation, as opposed to Shared Server Tomcat and Open BlueDragon Installation. Unfortunately, these don't indicate where the static web files are located, and how CFML requests are handled.