How to Host Your Clojure App on OpenShift - Archived

List will be processed on OpenShift picture
Today we shall explore deploying a Clojure application on top of OpenShift. We will use Leiningen to manage the applications. This is not the only way to deploy Clojure applications so I will explore more options in following parts of this (mini)series.

Clojure

Let’s start by exploring what actually is Clojure. I have to admit, I am no expert on it (at all) and I am learning about this technology myself. So, what does the official documentation say?

Clojure is a dynamic programming language that targets the Java Virtual Machine (and the CLR, and JavaScript). It is designed to be a general-purpose language, combining the approachability and interactive development of a scripting language with an efficient and robust infrastructure for multithreaded programming. Clojure is a compiled language - it compiles directly to JVM bytecode, yet remains completely dynamic. Every feature supported by Clojure is supported at runtime. Clojure provides easy access to the Java frameworks, with optional type hints and type inference, to ensure that calls to Java can avoid reflection.

This first thing that you realize when you see some Clojure code – it looks different. Yes! Clojure is a Lisp dialect. For function calls it always uses prefix notation

(func arg1 arg2 ...)

Clojure is a functional language. It provides immutable data structures and functions first-class citizens – you can define them, pass them around, use them as you would use object in Java. Clojure is also a dynamic language that provides interoperability with the JVM (or CLR or other platforms it can be compiled on).

Clojure provides REPL for dynamic use of the language. However I was told people actually use REPL to develop applications – how? Well, I am not yet there ;)

Clojure was designed with concurrency in mind. It provides rich features to handle a lot of complex tasks connected with concurrency, as well as it builds on top of it’s functional foundations.

Leiningen

Leiningen is a management tool for Clojure. Think of it as Maven squared :) It will help you during development but can also be used during deployment. It handles all the required and tedious things that occur during development – from dependency management to artifact building.

To get started it is as simple as downloading one file and running it (in the following examples I assume you are using a unix-like system. Windows users, please refer to the Leiningen site)

Leiningen will download Clojure and will allow you to get started right away.

Defining new project

Let’s start by defining new project. Out project will be super-simple web application and we will use Leiningen to manage the project. In some directory create a file project.clj with content like this:

(defproject clojureapp "0.0.1-SNAPSHOT"
    :dependencies [[org.clojure/clojure "1.5.1"]
                   [http-kit "2.1.12"]]
    :main webapp)

Here we do define new project called clojureapp with version 0.0.1-SNAPSHOT and we define some dependencies. First we define the version of Clojure we actually depend upon- we can think of Clojure as a library and Leiningen as a frontend to it. The second dependency is http-kit which is a framework for building HTTP applications. It is small, fast and just works. Great for a simple example.

The last thing we define is the entry-point to our application. The main method will be called in the webapp namespace. To make things simple, we can think of namespaces as packages in Java.

Done, we defined all the required parts for our application. Now, we can start building the application itself.

Building new application

In the same directory where you created project.clj, create a directory src and in that directory create a new file called webapp.clj with the following content

(ns webapp
  (:use org.httpkit.server))
 
(defn app [req]
    {:status  200
        :headers {"Content-Type" "text/html"}
        :body    "hello HTTP!"})
 
(defn -main [& args]
  (let [port (Integer/parseInt (get (System/getenv) "OPENSHIFT_CLOJURE_HTTP_PORT" "8080"))]
    (let [ip (get (System/getenv) "OPENSHIFT_CLOJURE_HTTP_IP" "0.0.0.0")]
  (run-server app {:ip ip :port port}))))

So, what is happening there? First we define new namespace called webapp and we import functions from the org.httpkit.server namespace. This will allow us later start new HTTP server.

Second step is to define new function called app with one parameter req. What the function does it to return new Map with three keys. I believe this should be pretty self-explanatory.

Third we create a new function main that takes one argument. It contains all the arguments that were passed in on the command line. Do you see any similarities to Java? Inside the function there are defined new bindings for ip and port where the server will bind to. This could be done much simpler, but this way we provide compatibility with OpenShift as well as local execution. Lastly we start new server.

Done. Simple? Yes! Different? YES!

Starting the application

So, we have the application, we have you project defined. What to do now? Let’s start it. Navigate to the directory where you saved the project.clj file. And we shall use Leiningen to start it. The server will bind to 0.0.0.0:8080 as the default values we specified in the code, when the OPENSHIFT_ variables are not present.

lein run

It should download some dependencies and then hang, if so, navigate in your browser to

http://localhost:8080/

Done. You have build your first application in Clojure.

Deploying to OpenShift

So, you may want to deploy your application to a PaaS (or Cloud in general). For those of us who are starting with Clojure I built a basic OpenShift cartridge that uses Leiningen to manage the application and you can find it on Github. To get started just create a new OpenShift application with that cartridge

rhc app create <myapp> http://cartreflect-claytondev.rhcloud.com/github/openshift-cartridges/clojure-cartridge

It will create new application on OpenShift, bring the Clojure plugin into OpenShift, and then it will clone the remote code repository locally. If you navigate in the local git respository with the same name as myapp, you will see a simple application we could also build locally.

Deploy to OpenShift

Let’s open the file that contains the web application src/webapp.clj and change the text

hello HTTP!

to

hello HTTP2!

Once we have the file changed, we deploy the code to OpenShift. To do so, we commit the files to git and will push it to OpenShift

git add .
git commit -m "My first change"
git push

Now, you have really deployed your first application to OpenShift. You can follow up from here to more complex Clojure adventures.

Conclusion

Clojure is different than most of the popular languages, however it seems very powerful and not at all complex as it first appears. I would encourage anyone to take a look into. You can also deploy applications in Clojure on OpenShift. Either by using the aforementioned cartridge, or by using more complex Immutant application server. We will take a look into Immutant in a follow up blog post.

What’s Next?

Categories
Java
Tags
, ,
Comments are closed.