How To Run Apache Tomcat 8 on OpenShift

Apache Tomcat 8 on OpenShift OpenShift PaaS gives developers the ability to try out new unsupported frameworks, programming languages, and servers. Today, while learning about WebSockets I learned that the current development version of Apache Tomcat i.e. version 8, has support for JSR356. JSR356 provides standard Java API for WebSockets. Although Apache Tomcat 7 provides support for WebSockets, it uses its own proprietary API. So, in order to test the JSR356 standard based WebSockets support in Apache Tomcat 8, I decided to give it a try. However, rather than installing Apache Tomcat 8 on my local development machine, I decided to install it on OpenShift.

In this post, I'll show you the steps to run Apache Tomcat 8 on OpenShift.

Apache Tomcat 8 brings support for a lot of Java EE 7 features like upgrading to Servlet 3.1, JSP 2.3 , Expression language 3.0, and some other tomcat specific features. There is not much documentation around all the features that will be added in Apache Tomcat 8 but I found these presentation slides useful.

OpenShift already has best in class Java support with Tomcat 6 , Tomcat 7 , JBoss AS7, and JBoss EAP 6 already bundled with it. You can also run Jetty or GlassFish on it using DIY cartridges. OpenShift also provides support for Jenkins continuous integration server as well.

Prerequisites

Before we can start building the application, we'll have to do few setup tasks :

  1. Sign up for an OpenShift Account. It is completely free and Red Hat gives every user three free Gears on which to run your applications. At the time of this writing, the combined resources allocated for each user is 1.5 GB of memory and 3 GB of disk space.

  2. Install the rhc client tool on your machine. The rhc is a ruby gem so you need to have ruby 1.8.7 or above on your machine. To install rhc, just type

sudo gem install rhc

If you already have one, make sure it is the latest one. To update your rhc, execute the command shown below.

sudo gem update rhc

For additional assistance setting up the rhc command-line tool, see the following page: https://openshift.redhat.com/community/developers/rhc-client-tools-install.

  1. Setup your OpenShift account using rhc setup command. This command will help you create a namespace and upload your ssh keys to OpenShift server.

Step 1 : Create an application

We will start by creating an OpenShift DIY application. The name of the application will be tomcat8. The DIY cartridge type provides a sandbox to try and test unsupported things. To know more, you can read about DIY here.

$ rhc app create tomcat8 diy

This will create an application container for us, called a gear, and setup all of the required SELinux policies and cgroup configuration. OpenShift will also setup a private git repository for you and clone the repository to your local system. Finally, OpenShift will propagate the DNS to outside world. The application will be accessible at http://tomcat8-domain-name.rhcloud.com/. Replace domain-name with your own unique domain name. This gear will already have Java 7 installed on it.

Step 2 : Stop the application

By default the DIY application will have a ruby server running on it. Since we will be installing Tomcat 8 we need to stop the server.

$ rhc app stop -a tomcat8
RESULT:
tomcat8 stopped

Step 3 : Delete unwanted files

The DIY folder under the Tomcat 8 folder has a couple of files which define a simple ruby web server and sample index.html file. Since we don't need them we will just delete them.

$ cd tomcat8
$ rm diy/index.html 
$ rm diy/testrubyserver.rb

For Windows users please use del instead of rm

Also, there are start and stop scripts under .openshift/action_hooks folder to start and stop the test ruby server. We will remove the start and stop scripts and replace them with new files.

$ rm .openshift/action_hooks/start 
$ rm .openshift/action_hooks/stop
$ touch .openshift/action_hooks/start
$ touch .openshift/action_hooks/stop

For Windows users, the touch command just creates a blank text file. Please do this however you feel comfortable on Windows, but please make sure they end up in the right directory.

Step 4 : Commit and push the changes

Once we have deleted the scripts and replaced them with empty files, we need to push the changes to the OpenShift application so that our changes are applied.

$ git commit -am "deleted unwanted files and replaced start and stop scripts"
$ git push

Step 5 : SSH into application gear and clone Tomcat 8 source

Apache Tomcat 8 is currently in development and I couldn't find any nightly snapshots so we will building tomcat from the source. We will ssh into our application gear and clone the Tomcat git repository as shown below. Every OpenShift gear already has git installed. The commands below assume you are in the git repository directory (tomcat8) on your local machine.

$ rhc ssh -a tomcat8
$ cd $OPENSHIFT_DATA_DIR 
$ mkdir source
$ cd source/
$ git clone https://github.com/apache/tomcat.git
$ cd tomcat/

Step 6 : Build tomcat 8 source

Tomcat 8 code needs Ant to build the source code. Every OpenShift application gear has Ant installed so you can easily compile the source code. But before we do that we have to take some steps. We need to create a directory where tomcat 8 dependencies binaries should be downloaded. These binaries are required to build tomcat 8. We will download dependencies to $OPENSHIFT_DATA_DIR/dependencies.

$ cd $OPENSHIFT_DATA_DIR
$ mkdir dependencies 

Next we will rename build.properties.default to build.properties.

$ cd $OPENSHIFT_DATA_DIR
$ cd source/tomcat
$ mv build.properties.default build.properties

Change base.path property in build.properties to location of dependencies folder.

# ----- Default Base Path for Dependent Packages -----
# Please note this path must be absolute, not relative,
# as it is referenced with different working directory
# contexts by the various build scripts.
base.path=../../dependencies

Next we need to remove the dependency of build-docs target from deploy target as it gives an exception.

<target name="deploy" depends="package, build-tomcat-jdbc"
          description="Default. Builds a working Tomcat instance">

The exception I was getting is mentioned below. If anyone knows how to fix this, please post solution in comments section. I try adding ant-nodeps.jar to Ant path as suggested in a stackoverflow question but that didn't solve the problem

[xslt] java.lang.ClassNotFoundException: org.apache.tools.ant.taskdefs.optional.TraXLiaison

Now, run the ant build

$ ant clean
$ ant

This will take 3-4 minutes to finish.

Step 7 : Copying tomcat 8 executables

After the build finishes, the tomcat 8 executables will be in the output/build folder. Copy the artifacts to tomcat8 folder in $OPENSHIFT_DATA_DIR.

$ cd $OPENSHIFT_DATA_DIR
$ mkdir tomcat8
$ cd tomcat8
$ cp -r ../source/tomcat/output/build/* .

Now all the tomcat 8 related files are in the tomcat8 folder.

Step 8 : Modify server.xml

Now that we have built the tomcat source and copied it to the tomcat8 folder, we need to modify the server.xml file to specify the ports we want to use as well as the IP address to bind to. Because OpenShift is a multitenant environment, you will need to use the internal IP address that is provided to you. In order to find this address, run the following command:

$ env | grep OPENSHIFT_DIY_IP

Which should return something similar to as shown below.

OPENSHIFT_DIY_IP=127.8.97.129

We need to modify the server.xml file to respect this IP address as well as change the default ports that some of the services run on. The ports that are configured for other services will not work by default because OpenShift does not allow users to bind to any port below 15000 other than 8080. Because of this, we need to change the following configuration items. You can view the full working server.xml here. Just replace address value with $OPENSHIFT_DIY_IP value.

Old Connector:

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

New Connector:

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000" address="127.8.97.129"
               redirectPort="8443" />

Change the shutdown port

<Server port="8005" shutdown="SHUTDOWN">

to

<Server port="15005" shutdown="SHUTDOWN">

And finally change the AJP 1.3 connector on port 8009 as shown below.

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>

to

<Connector port="15009" protocol="AJP/1.3" redirectPort="8443" address="127.8.97.129" />

Step 9: Start the Tomcat servlet container

Finally we will start the tomcat 8 servlet container by executing startup.sh file.

$ cd ../bin
$ ./startup.sh && tail -f ../logs/*

This should start Tomcat as well as make it accessible to the outside world via port 80. You are probably asking yourself how it’s available on port 80 when we specifically set it to use 8080. OpenShift actually has a proxy setup that will pass all traffic coming to your host via port 80 to a local server you have running on port 8080. This port is specified in the system environment variable OPENSHIFT_DIY_PORT.

Verify that your tomcat server is running by pointing your browser to your application at tomcat-yourNamespace.rhcloud.com. You can view a sample Apache Tomcat 8 installation at http://tomcat8-cix.rhcloud.com/. You can view examples under http://tomcat8-cix.rhcloud.com/examples/.

If you want to use the Tomcat management console, add a user to the tomcat-users.xml file located in the conf directory. For example, add the following role and user to that file deleting what is already there:

<role rolename="manager-gui"/>
<user username="tomcat" password="openshift" roles="manager-gui"/>

Step 10 : Update start and stop action hooks

Finally, we need to update the start and stop action hooks so that they start and stop the tomcat. This is required so that you can manage tomcat from rhc command line tooling. So, when you run rhc app stop -a tomcat8 , it will stop tomcat 8 and when you will run rhc app start -a tomcat8 , it will start tomcat 8. Open the start script in .openshift/action_hooks folder and add the following lines.

cd $OPENSHIFT_DATA_DIR/tomcat8/bin
./startup.sh

To stop the Apache Tomcat 8, add following lines to stop the script

cd $OPENSHIFT_DATA_DIR/tomcat8/bin
./shutdown.sh

Lastly, commit the code and push it to application gear.

$ git commit -am "added start and stop commands"
$ git push

Do You Need a Quickstart?

If you don't want to follow all the steps, I have written a quickstart which automates all of the above mentioned steps. The quickstart is located at https://github.com/shekhargulati/openshift-tomcat8-quickstart. Just open a command line and execute the commands shown below.

rhc app create tomca8 diy
cd tomca8
git remote add upstream https://github.com/shekhargulati/openshift-tomcat8-quickstart.git
git pull -s recursive -X theirs upstream master
git push

Conclusion

In this blog, I showcased how you can use OpenShift to run Apache Tomcat 8. OpenShift provides you a platform to run bleeding edge technologies on it. In the next blog, I will showcase how we can develop realtime application using JSR 356 API. So, if you are looking for a platform to run your Java application, give OpenShift a try.

What's Next?

This is what I get when access http://tomcat8-joninazio.rhcloud.com/:

Proxy Error
 
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request GET /.
 
Reason: Error reading from remote server
---------------------------------------------------------------------------------------------------------
Apache/2.2.15 (Red Hat) Server at tomcat8-joninazio.rhcloud.com Port 80

Another questions:

1) How can I create WAR file in eclipse having a maven based structure project for openshift? 2) How to deploy the WAR file to tomcat8 webapps?

Thank you...

Cannot use WebSocket connection to vertx.io diy appliation. Socket freeze in pending state. SockJS failback to xhr long polling.

after doing ssh to application, ANT CLEAN or ANT IS NOT WORKING.. showing command not found...

please help.. want to create an Downloadable cartridge.. am an newbee to it.... any kind of help will be worthy... plzzz

When I tried to startup tomcat, I get a BindException on port 15005.

27-Oct-2013 09:38:57.250 SEVERE [main] org.apache.catalina.core.StandardServer.await StandardServer.await: create[localhost:15005]:
java.net.BindException: Permission denied
       at java.net.PlainSocketImpl.socketBind(Native Method)
       at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:376)
       at java.net.ServerSocket.bind(ServerSocket.java:376)
       at java.net.ServerSocket.<init>(ServerSocket.java:237)
       at org.apache.catalina.core.StandardServer.await(StandardServer.java:412)
       at org.apache.catalina.startup.Catalina.await(Catalina.java:746)
       at org.apache.catalina.startup.Catalina.start(Catalina.java:692)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       at java.lang.reflect.Method.invoke(Method.java:606)
       at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:352)
       at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:486)

For solve that, I must specify address on Server configuration like that:

<Server port="15005" shutdown="SHUTDOWN" address="127.8.97.129">

You need to use your OPENSHIFT_DIY_IP, you can view this by sshing into your application and then running this command env | grep IP

Any idea how can we add a myslq database to a tomcat dyi project?

rhc add-cartridge mysql-5.1 -a