How to integrate Clojure web applications into Apache

Note

Given that this OP was written about two years ago, instead of asking the same question again, I wonder if there are step-by-step instructions so that I can integrate Noir or another Clojure web application into Apache, be it Jetty, Tomcat or something else. Similar instructions exist for Django, and I think that I understand that Python runs in the case of Django as an engine, and not in a ring structure, so it’s more complicated with Clojure web applications.

Final note

I'm deeply in love with Clojure, and Compojure looks like a neat web framework.

But it all fell apart when I wanted to deploy my application on a regular application server such as Tomcat, like WAR. I really had to write custom call handlers for static files and resources that would work on both the local Jetty and Tomcat, because the storage handlers did not, and I had to manually add the root context.

I am negatively surprised that I had to write all this code in order to create a simple web application that could run on both Jetty and Tomcat. I have only three possible explanations:

  • No one uses Clojure / Compojure for anything other than local development with Jetty, i.e. in production
  • Everyone deploys Clojure / Compojure applications on a dedicated Jetty without a context root (LIke users do this using Node.js applications).
  • There is a very simple way to get around the problems that I encountered, I did not know about

Which one do you think is dealing? Or is it something else?

Edit:

Please note that creating a war file is no problem with Maven / Leiningen, not what I mean. I'm curious that I need to write so much code to get Compojure to work with Tomcat, basic things like static files and contextual understanding that should work out of the box.

+55
clojure deployment war compojure
Apr 01 '11 at 8:30
source share
7 answers

People embed Compojure applications in containers without Jetty servlets.

Departure:

Also check lein-war

+9
Apr 01 2018-11-11T00:
source share

I use a combination of the following to make it pretty painless:

Cake (including deployment team)

Cake template for web projects designed by Lau Jensen.

Vagrant (a Ruby VM management tool (Virtualbox) that uses Chef or Puppet)

VPS (from Slicehost)

The key part is the webdev template that Lau made. The webdev folder should be placed in ~/.cake/templates . To create a new project based on it, use:

 cake new webdev *projectname* 

Note that the template includes log4j and Java mail, which may / should be excluded if they are not needed. The following assumes that you are using Enlive and Mustache, but changing this to Compojure / Hiccup is trivial if it is your poison.

The template takes care of serving the application from the berth in development (you just eval server.clj) and works like a war when working under Tomcat. Routes remain identical when deployed to a server like ROOT.war under Tomcat. All static files should be located in the resource directory. Jetty will service them from there (thanks to Ring Ring middleware). In production, they are moved to the root of webapp and sent from there to Tomcat (web.xml takes care of this).

The Devbox folder contains the Vagrant file and cookbooks needed to create a virtual machine with Tomcat installed. I use the cake to expand the .war file in the /home/vagrant (this is determined from the dev context definition in project.clj). The .war file is symbolically linked to Tomcat webapps dir ( /var/lib/tomcat6/webapps ) as ROOT.war. For more information on how to use Vagrant, see the Vagrant Website.

This gist shows an example of how to adapt project.clj to use the cake deployment command. In the example, two contexts @dev and @prod are created that can be expanded for use:

 cake deploy @dev / cake delpoy @prod 

I put together a webdev Cake template and Vagrant files in this zip .

+11
Apr 01 '11 at 17:40
source share

I had some success using leiningen-war to generate a common war file (assuming you use leiningen, of course). It allows you to specify the locations for static html, the location of web.xml and other resources in the project.clj file.

It was not easy for me to create a common war file that I could deploy to JBoss (running Tomcat as a servlet container), but I think you should be familiar with the web.xml format. I like to create my own web.xml more, so I like this approach more.

It seems that the person behind the leiningen-war is now recommending the lein-ring . I started looking at this, but so far I have not been able to get a common war file from him.

I agree that accounting for production deployment is a weakness here.

+6
Apr 01 '11 at 16:01
source share

I use Noir , a web framework built on top of Ring and Compojure.

I created a project using lein noir new my-proj . Then I created the my-proj/web directory and added the following lines to

 project.clj: :compile-path "web/WEB-INF/classes" :library-path "web/WEB-INF/lib" :ring {:handler project.server/handler} 

I set the my-proj/web directory as the context root during the development of Tomcat.

For static work with files, I put things in the my-proj/resources/public directory. To access (read / write) files through the code, you can use :servlet-context from the call request header. With the above settings, the context path: (.getRealPath (ring-request-header :servlet-context) "/WEB-INF/classes/myfile.txt") . Myfile.txt is under my-proj/resources .

+3
Sep 20 '11 at 11:12
source share

If you are deploying to the Google App Engine, here is a great blog http://compojureongae.posterous.com/

You can still get some useful tips, even if you are not using GAE.

+2
Apr 01 2018-11-11T00:
source share

I launched the Compojure + Vaadin application (over 6 months). The packaging was done using the lein-war plugin, and I did not encounter any serious problems.

The application is called halo, which is contained in the halo.war file, context / halo, and the tomcat server also runs Hudson and another custom-made application. Vaadin correctly resolves all of my static files, CSS, images ... Basically I used a blog post to write the little glue needed for it.

In another note, I also run Noir on Heroku and there were no problems with packaging and deployment, and this is also in production.

This is not directly related to your Compojure question, but Clojure in production in web applications, yes, definitely.

+2
Aug 04
source share

If you are using a call-based server (compojure, noir / lib-noir, luminus, etc.) and want to deploy as uberjar to avoid

 "Failed to load Main-Class manifest attribute from your-uberjar.jar" 

just create uberjar with lein ring uberjar . Pay attention to the addition of "ring" to lein uberjar. It is assumed that you are using the lein-ring plugin.

+1
Apr 08 '13 at
source share



All Articles