I already blog posted about how to deploy TomEE on cloudfoundry using the standalone framework (TomEE on CloudFoundry). It was mainly based on the tomee-maven-plugin to create a tomee ready to start and cloudfoundry maven plugin to deploy it.
The main competitor of CloudFoundry is OpenShift. The question is can we do the same?
OpenShift doesn’t have a maven plugin (or i missed it) but i developped one here: OpenShift Maven Plugin.
Now we have tomee-maven-plugin and openshift-maven-plugin we just miss some configuration to be able to deploy our application quickly.
The project
For the sample i’ll take a simple war project.
The OpenShift cartridge selection
With OpenShift you deploy your application in “standalone” cartridges (it can be any container like Tomcat, TomEE, JBoss AS…or any runtime like PHP, NodeJS…). There is a TomEE cartridge (here) but it needs to be installed on an OpenShift node (server side). Since that’s not always possible or simply because sometimes you customize TomEE enough to not be able to rely on a default installation we’ll start from a DIY (do it yourself) cartridge.
The configuration
Note: i use maven property openshift.base to represent the folder containing the customized DIY cartridge.
Maven
What do we need on maven side?
- create a tomee containing our application
- deploy our customized DIY cartridge to OpenShift
TomEE maven plugin
What are the contraint on our TomEE?
- our TomEE maven plugin will use the exploded war to be able to push to OpenShift lighter diff (OpenShift relies on git)
- we’ll remove all TomEE webapps since we don’t need it
- we want our application to be the root one (context “/”).
- we don’t need to create a zip of our tomee or to attach it to maven lifecycle
Here is the XML version:
<plugin> <groupId>org.apache.openejb.maven</groupId> <artifactId>tomee-maven-plugin</artifactId> <version>1.6.0-SNAPSHOT</version> <executions> <execution> <id>create-tomee</id> <phase>package</phase> <goals> <goal>build</goal> </goals> <configuration> <attach>false</attach> <!-- maven doesn't need to take tomee as an artifact --> <zip>false</zip> <!-- we deploy an exploded version --> <removeTomeeWebapp>true</removeTomeeWebapp> <!-- we don't do remote EJBs --> <catalinaBase>${openshift.base}/diy/tomee</catalinaBase> <!-- matches our action_hooks --> <context>ROOT</context> <!-- / context --> <warFile>${project.build.directory}/${project.build.finalName}</warFile> <!-- exploded war file for better diff handling --> <keepServerXmlAsthis>true</keepServerXmlAsthis> <!-- otherwise our variables will be replaced --> </configuration> </execution> </executions> </plugin>
You can note it will be executed during package phase. That’s just to avoid to call multiple goals before deploying.
Note i set keepServerXmlAsthis to true too, i’ll explain why in the part about the OpenShift hooks.
OpenShift maven plugin
OpenShift maven plugin supports credentials to be passed in the plugin configuration block but if you already have set up rhc (the OpenShift client) you probably have a ~/.openshift/express.conf the plugin is able to read to extract your OpenShift url, user and password (this one is not by default in the file and you need to add the base64 of your password as value of the key “maven_plugin_password”).
Here the constraints are pretty simple:
- we need to match the OpenShift domain and application we want to deploy
- we don’t deploy in a Tomcat or TomEE (where webapps/ is handled particularly) so we need to deploy the whole repository we created
- we need to add action_hooks (see next part)
So here is the XML version:
<plugin> <groupId>com.worldline.maven</groupId> <artifactId>openshift-maven-plugin</artifactId> <version>0.1-SNAPSHOT</version> <configuration> <application>dyot</application> <domain>blois</domain> <binary>${openshift.base}</binary> <!-- we deploy a diy --> <useWebapps>false</useWebapps> </configuration> </plugin>
The action hooks stuff is not explicit since by default the plugin synchronizes src/main/openshift directory with the git repository of your application (our DIY cartridge).
The hooks
Now we are able to push a TomEE on OpenShift but if you just do it it will not start/stop (or at least not as expected).
OpenShift uses environment variables to pass to the cartridges the host/port/… the cartridge needs to listen to be accessible.
So to match this configuration we’ll create a custom server.xml in src/main/tomee/conf (synchronized by tomee-maven-plugin by default) containing:
<?xml version='1.0' encoding='utf-8'?> <Server address="OPENSHIFT_DIY_IP" port="SHUTDOWN_PORT" shutdown="SHUTDOWN"> <Listener className="org.apache.tomee.catalina.ServerListener" /> <Listener className="org.apache.catalina.core.JasperListener" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <Service name="Catalina"> <Connector port="HTTP_PORT" protocol="HTTP/1.1" connectionTimeout="20000" address="OPENSHIFT_DIY_IP" /> <Engine name="Catalina" defaultHost="OPENSHIFT_DIY_IP"> <Host name="OPENSHIFT_APP_DNS" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service> </Server>
Here you can see why keepServerXmlAsThis was set to true in tomee-maven-plugin configuration: if not host and ports will be replaced by the one provided in the plugin configuration (if not the default one ie localhost for the host, 8080 for the http port…).
Now we just need to say our cartridge to replace the variables of this server.xml and how to start/stop our TomEE.
To do so just create a folder “.openshift/action_hooks” in src/main/openshift (which will be synchronized by the openshift-maven-plugin) containing a start and a stop script.
The stop script is trivial since it just calls TomEE shutdown.sh script:
#! /bin/bash nohup sh $OPENSHIFT_DATA_DIR/tomee/bin/shutdown.sh
The start one is a bit more complicated since it will synchronize the git working copy of the OpenShift node with the runtime instance, replace the variable in the server.xml and start the server:
#! /bin/bash DEST=$OPENSHIFT_DATA_DIR/tomee/ SERVER_XML=$DEST/conf/server.xml LOGS=$DEST/logs rm -r $DEST cp -r $OPENSHIFT_REPO_DIR/diy/tomee/ $DEST sed -i 's/OPENSHIFT_DIY_IP/'$OPENSHIFT_DIY_IP'/g' $SERVER_XML sed -i 's/OPENSHIFT_APP_DNS/'$OPENSHIFT_APP_DNS'/' $SERVER_XML sed -i 's/HTTP_PORT/'$OPENSHIFT_DIY_PORT'/' $SERVER_XML sed -i 's/SHUTDOWN_PORT/'$RANDOM'/' $SERVER_XML rm -rf $LOGS ln -s $OPENSHIFT_DIY_LOG_DIR $LOGS nohup sh $DEST/bin/startup.sh
The deployment
If you didn’t already created your application on OpenShift just execute the command:
mvn openshift:create-application -Dopenshift.cartridge=diy-0.1
It will create your application using the DIY cartridge.
Then to deploy simply run:
mvn package mvn openshift:update-application
hi Romain. Please you can please explain me how set the usename and password of my account openshift into the OpenShift maven plugin ?
1) if i would deploy a new tomee on openshift using a computer that not has installed rhclient it is possible ? I not have into the pc the ~/.openshift/express.conf because it is another computer .
2)before to use the openshift maven plug in i have to create the cartridge diy from the website of openshift for get the password ssh-rsa ????????? or it work without ssh-rsa??
3) HOw i can set the mysql connection into tomee.xml whit sed -i ?????????
Basically username is a subtag of configuration of the plugin (tag name is “user”) and password too but you can put the password in ~/.openshift/express.conf (even without rhc) with the key maven_plugin_password and a base64 value of your password. Side note: default_rhlogin is read too for username in this file.
Your openshift server has to have the needed cartridge(s) installed yes.
To use openshift mysql you can use templating of tomee (JdbcUrl = ${name of the var in openshift})
for set the datasource into tomee.xml i have to use this example????
http://whyjava.wordpress.com/2012/11/21/configuring-jndi-datasource-with-openshift-tomcat-cartridge/
Resource name=”jdbc/postgresqldb” auth=”Container” type=”javax.sql.DataSource”
username=”${env.OPENSHIFT_POSTGRESQL_DB_USERNAME}” password=”${env.OPENSHIFT_POSTGRESQL_DB_PASSWORD}”
url=”jdbc:postgresql://${env.OPENSHIFT_POSTGRESQL_DB_HOST}:${env.OPENSHIFT_POSTGRESQL_DB_PORT}/${env.OPENSHIFT_APP_NAME}”
driverClassName=”org.postgresql.Driver” initialSize=”5″ maxWait=”5000″
maxActive=”120″ maxIdle=”5″ validationQuery=”select 1″
poolPreparedStatements=”true”>
the example above it is set into server.xml .of a tomcat on openshift.
So i you ask:
i can refer into tomee.xml the ${env.OPENSHIFT_MYSQL_DB_USERNAME} and other??
it work also with the diy????
finally i think to write my tomee.xml with the following entry :
JdbcDriver com.mysql.jdbc.Driver
JdbcUrl jdbc:mysql://${env.OPENSHIFT_MYSQL_DB_HOST}:${env.OPENSHIFT_MYSQL_DB_PORT}/${env.OPENSHIFT_APP_NAME}”
UserName “${env.OPENSHIFT_MYSQL_DB_USERNAME}”
Password “${env.OPENSHIFT_M§YSQL_DB_PASSWORD}”
JtaManaged true
or i can use the Resources.xml into web.inf of a single webapp deployed into tomee into openshift?
yu can that it can work the configuration above?
into the i have to use the :
UserName “${env.OPENSHIFT_MYSQL_DB_USERNAME}”
or
UserName ${env.OPENSHIFT_MYSQL_DB_USERNAME}
env? I used ${OPENSHIFT_MYSQL_DB_USERNAME} directly
but go at
https://www.openshift.com/blogs/jndi-tomcat-configuration-howto
it use ìinto sever.xml for tomcat:
———————–
whi into tomee.xml you don’t use the env ???
cause it uses tomee resources then. We’ll merge it in next versions normally.