Enabling Tomcat 7
Nuxeo is currently packaged with a Tomcat 6 instance. The following allows it to work in a Tomcat 7 instance.
First get a Tomcat 7 instance and unzip it into /opt/tomcat-7.0.30
cd /opt unzip apache-tomcat-7.0.30.zip mv apache-tomcat-7.0.30 tomcat-7.0.30
Then convert Nuxeo to work in that Tomcat 7 instance:
cd /opt unzip nuxeo-coreserver-5.7-I20121123_0116-tomcat.zip T6=nuxeo-coreserver-5.7-I20121123_0116-tomcat T7=tomcat-7.0.30 rm -rf $T7/nxserver rm -rf $T7/templates rm -rf $T7/endorsed cp -R $T6/nxserver $T7/ cp -R $T6/templates $T7/ cp -R $T6/endorsed $T7/ cp $T6/bin/nuxeoctl $T7/bin/ cp $T6/bin/nuxeo.conf $T7/bin/ cp $T6/bin/nuxeo-launcher.jar $T7/bin/ cp $T6/lib/log4j.xml $T7/lib/ cp $T6/lib/nuxeo-*.jar $T7/lib/ cp $T6/lib/commons-logging-*.jar $T7/lib/ cp $T6/lib/commons-lang-*.jar $T7/lib/ cp $T6/lib/freemarker-*.jar $T7/lib/ cp $T6/lib/log4j-*.jar $T7/lib/ cp $T6/lib/lucene-*.jar $T7/lib/ cp $T6/lib/mail-*.jar $T7/lib/ cp $T6/templates/tomcat7/conf/server.xml.nxftl $T7/templates/common-base/conf/server.xml.nxftl chmod +x $T7/bin/*.sh
In
bin/nuxeo.conf
, remove or commentnuxeo.wizard.done=false.
Building the Tomcat+WAR
This builds a ZIP containing a WAR and a few additional files, designed to be unpacked at the root of a Tomcat instance. It cannot be used directly as a pure WAR.
cd /opt/tomcat-7.0.30
bin/nuxeoctl pack /opt/nuxeotomcatwar.zip
The resulting ZIP is all that's needed for the rest of the instructions.
Preparing a full Tomcat 7 with Nuxeo WAR
Set up a new Tomcat 7 from scratch with the WAR that was just built.
cd /opt rm -rf tomcat-7.0.30 unzip apache-tomcat-7.0.30.zip mv apache-tomcat-7.0.30 tomcat-7.0.30 cd tomcat-7.0.30 chmod +x bin/*.sh unzip /opt/nuxeotomcatwar.zip
Now update the WAR to work in a Tomcat 7 instance without references to the toplevel
>lib/
directory:mv lib/commons-*.jar lib/h2-*.jar lib/lucene-*.jar lib/nuxeo-*.jar webapps/nuxeo/WEB-INF/lib/ rm lib/derby-*.jar
Finally we must set up the Nuxeo datasources inside the WAR (instead of from the toplevel
server.xml
in a standard Nuxeo setup, which is more convenient when possible).Edit the file
webapps/nuxeo/META-INF/context.xml
. In this file the<Resource>
elements that point to a global configuration inserver.xml
must be replaced by explicit resources:<Resource name="jdbc/NuxeoDS" accessToUnderlyingConnectionAllowed="true" auth="Container" driverClassName="org.h2.Driver" maxActive="100" maxIdle="30" maxWait="10000" password="" type="javax.sql.DataSource" url="jdbc:h2:nuxeo" username="sa" validationQuery=""/> <Resource name="jdbc/nxsqldirectory" accessToUnderlyingConnectionAllowed="true" auth="Container" driverClassName="org.h2.Driver" maxActive="100" maxIdle="30" maxWait="10000" password="" type="javax.sql.DataSource" url="jdbc:h2:nuxeo" username="sa" validationQuery=""/> <Resource name="jdbc/nxrelations-default-jena" accessToUnderlyingConnectionAllowed="true" auth="Container" driverClassName="org.h2.Driver" maxActive="100" maxIdle="30" maxWait="10000" password="" type="javax.sql.DataSource" url="jdbc:h2:nuxeo" username="sa" validationQuery=""/> <Resource name="jdbc/comment-relations" accessToUnderlyingConnectionAllowed="true" auth="Container" driverClassName="org.h2.Driver" maxActive="100" maxIdle="30" maxWait="10000" password="" type="javax.sql.DataSource" url="jdbc:h2:nuxeo" username="sa" validationQuery=""/> <Resource name="jdbc/nxaudit-logs" accessToUnderlyingConnectionAllowed="true" auth="Container" driverClassName="org.h2.Driver" maxActive="100" maxIdle="30" maxWait="10000" password="" type="javax.sql.DataSource" url="jdbc:h2:nuxeo" username="sa" validationQuery=""/> <Resource name="jdbc/nxjbpm" accessToUnderlyingConnectionAllowed="true" auth="Container" driverClassName="org.h2.Driver" maxActive="100" maxIdle="30" maxWait="10000" password="" type="javax.sql.DataSource" url="jdbc:h2:nuxeo" username="sa" validationQuery=""/> <Resource name="jdbc/placeful_service_ds" accessToUnderlyingConnectionAllowed="true" auth="Container" driverClassName="org.h2.Driver" maxActive="100" maxIdle="30" maxWait="10000" password="" type="javax.sql.DataSource" url="jdbc:h2:nuxeo" username="sa" validationQuery=""/> <Resource name="jdbc/nxwebwidgets" accessToUnderlyingConnectionAllowed="true" auth="Container" driverClassName="org.h2.Driver" maxActive="100" maxIdle="30" maxWait="10000" password="" type="javax.sql.DataSource" url="jdbc:h2:nuxeo" username="sa" validationQuery=""/> <Resource name="jdbc/nxuidsequencer" accessToUnderlyingConnectionAllowed="true" auth="Container" driverClassName="org.h2.Driver" maxActive="100" maxIdle="30" maxWait="10000" password="" type="javax.sql.DataSource" url="jdbc:h2:nuxeo" username="sa" validationQuery=""/>
In the above we use an embedded H2 database. Configuration for an external database server would need to use a different JDBC URL.
The above exploded WAR can now be packed into a zipped WAR:
cd /opt/tomcat-7.0.30/webapps/nuxeo zip -r /opt/nuxeo.war .
The resulting
/opt/nuxeo.war
is now compatible with any modern application server.
Deploying to CloudFoundry
Patching the WAR
If you try to deploy the above WAR on CloudFoundry you'll get an error: Too many open files
This is due to the fact that CloudFoundry has a limit of 256 file descriptors open, and Nuxeo uses more.
In fact, it's the Tomcat classloader that uses a lot of file descriptors, because for performance reasons it keeps one open file descriptor per JAR in the WEB-INF/lib
directory. To work around this problem, the non-Nuxeo JARs present in WEB-INF/lib
can be merged into one big JAR, which solves the problem.
cd webapps/nuxeo/WEB-INF/lib
mkdir tmp
mkdir bigjar
mv *.jar tmp/
mv tmp/nuxeo-*.jar .
cd bigjar
for i in ../tmp/*.jar; do unzip $i; done
rm META-INF/*.SF META-INF/*.DSA
zip -r ../bigjar.jar .
cd ..
rm -rf tmp/ bigjar/
Deploying Tomcat 7 + Nuxeo
Before the above Tomcat 7 instance can be set up as a full “standalone” application in CloudFoundry, it needs to be modified to take configuration information (like TCP ports) from the CloudFoundry PaaS framework. (These are standard instructions for using a stock Tomcat in CloudFoundry, you'll find them elsewhere.)
The following is added to
bin/catalina.sh
:# USE VCAP PORT IF IT EXISTS, OTHERWISE DEFAULT TO 8080 if [ -z ${VCAP_APP_PORT} ]; then export VCAP_APP_PORT=8080 fi export JAVA_OPTS="-Dport.http.nonssl=$VCAP_APP_PORT $JAVA_OPTS"
The
bin/startup.sh
is changed to not run in the background (run
instead ofstart
):exec "$PRGDIR"/"$EXECUTABLE" run "$@"
Finally the non-useful ports in
conf/server.xml
are commented out:Replace 8005 with -1 to deactivate the Tomcat SHUTDOWN port,
Comment out the AJP connector on port 8009,
Replace 8080 with the expression
${port.http.nonssl}
to use the PaaS configuration.
The Tomcat 7 application including the Nuxeo WAR is now ready to be pushed to CloudFoundry as a “Standalone Application”. For this, standard CloudFoundry mechanisms are used, don't forget to specify the Java 7 runtime:
vmc push --runtime=java7 myapp
The following CloudFoundry YML manifest corresponds to a full setup (
myapp
should be replaced by your namespace):--- applications: .: mem: 1G instances: 1 url: myapp.cloudfoundry.com framework: info: mem: 64M exec: description: Standalone Application name: standalone command: bin/startup.sh name: myapp runtime: java7
Testing Nuxeo CMIS
Once deployed and started, Nuxeo CoreServer does not provide a web-accessible graphical user interface (because the CoreServer version doesn't have those), but it can be addressed through a CMIS client like the Apache CMIS Workbench available at http://chemistry.apache.org/java/developing/tools/dev-tools-workbench.html .
It must point to Nuxeo, whose CMIS address is described by the Nuxeo startup page, usually it is of the form http://NUXEO_SERVER/nuxeo/atom/cmis
. The default Nuxeo user/password is Administrator/Administrator.