18 Mar 2015 · Software Engineering

    How to Deploy a Compojure Application to OpenShift

    6 min read
    Contents

    Introduction

    OpenShift is Red Hat’s cloud computing platform as a service. It’s based on open source OpenShift Origin project. The platform officially supports a number of languages: Java, PHP, Ruby, Node.js, Python and Perl.

    Since the platform is open source, other languages and platforms are supported by community-maintained cartridges. A cartridge is a set of scripts and configuration files that prepares a gear for your application. Gears are containers for your application, with allocated CPU, memory, disk, and network bandwidth.

    One of community-supported languages is Clojure.

    In this tutorial we will create a Hello World Compojure web application using the community-maintained cartridge and deploy it to OpenShift.

    Prerequisites

    For developing and deploying a Clojure application using this tutorial you will need:

    Installing OpenShift Client Tools

    OpenShift client tools (rhc) is a Ruby gem that provides commands for creating and managing OpenShift applications.

    If you already have Ruby and Git on your development machine, you can install rhc with:

    gem install rhc

    If you don’t have Ruby and Git, follow installation instructions in the OpenShift Getting Started guide. It covers installation instructions on a number of platforms and development environments, including Windows, OS X, Fedora, RHEL/CentOS, Debian/Ubuntu, Eclipse IDE and JBoss Developer Studio.

    After rhc has been installed, run the setup wizard:

    rhc setup

    Choose the default OpenShift server and enter your email and password to log in. The wizard will detect your SSH keys, or generate a new pair for you if you don’t have one. After you have logged in, the wizard will check if everything is set up correctly and if Git is installed.

    Create an OpenShift Application

    Now that rhc has been set up correctly, let’s use it to generate a new OpenShift application based on the Clojure cartridge:

    $ rhc app create helloworld http://cartreflect-claytondev.rhcloud.com/github/strika/clojure-cartridge
    
    ...
    
    Your application 'helloworld' is now available.
    
      URL:        http://helloworld-strika.rhcloud.com/
      SSH to:     54e5a4b6fcf9339c9c1111dc@helloworld-strika.rhcloud.com
      Git remote: ssh://54e5a4b6fcf9339c9c1111dc@helloworld-strika.rhcloud.com/~/git/helloworld.git/
      Cloned to:  /home/vagrant/community-playground/helloworld

    The command will create a new application on OpenShift named helloworld, create a new directory on your development machine named helloworld and generate a simple Clojure application. It will also initialize a Git repository and set origin remote to OpenShift server.

    The command has useful output. It displays:

    • The URL where your application will be available after deploy
    • SSH URL – so you can SSH to the machine and debug or inspect the running application
    • The Git remote where you need to push to deploy the application
    • The directory on your development machine where the application is cloned

    This and other useful information is available on the application page on OpenShift. To see the list of all your applications visit https://openshift.redhat.com/app/console/applications. Later in the tutorial we will use the URL of the application to see if the application is deployed and running.

    Generate a Compojure Application

    Since we want to create an application based on Compojure, let’s remove the files that rhc generated:

    rm -rf helloworld/*

    Now, generate a Compojure-based Clojure project:

    lein new compojure helloworld --force

    Here we tell Leiningen to use the compojure template to generate a new application named helloworld. --force option is required, since the helloworld directory already exists.

    Commit new code:

    cd helloworld
    git add --all .
    git commit -m "Replace template with Compojure application"

    To start the application on OpenShift, the server must be runnable with the lein run command. If you try to run the application now, you will see the following error message:

    $ lein run
    No :main namespace specified in project.clj.

    Let’s add the ring-jetty-adapter to our list of dependencies in project.clj and configure the helloworld.handler namespace to be our main application point:

    (defproject helloworld "0.1.0-SNAPSHOT"
      :description "FIXME: write description"
      :url "http://example.com/FIXME"
      :min-lein-version "2.0.0"
      :dependencies [[org.clojure/clojure "1.6.0"]
                     [compojure "1.3.1"]
                     [ring/ring-defaults "0.1.2"]
                     [ring/ring-jetty-adapter "1.3.2"]]
      :plugins [[lein-ring "0.8.13"]]
      :ring {:handler helloworld.handler/app}
      :main helloworld.handler
      :profiles
      {:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
                            [ring-mock "0.1.5"]]}})

    In the src/helloword/handler.clj file, require the run-jetty function from the ring.adapter.jetty namespace and add the -main method that will be executed when the lein run command is executed:

    (ns helloworld.handler
      (:require [compojure.core :refer :all]
                [compojure.route :as route]
                [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
                [ring.adapter.jetty :refer [run-jetty]]))
    
    (defroutes app-routes
      (GET "/" [] "Hello World")
      (route/not-found "Not Found"))
    
    (def app
      (wrap-defaults app-routes site-defaults))
    
    (defn -main [& args]
      (let [ip (get (System/getenv) "OPENSHIFT_CLOJURE_HTTP_IP" "0.0.0.0")
            port (Integer/parseInt (get (System/getenv) "OPENSHIFT_CLOJURE_HTTP_PORT" "8080"))]
        (run-jetty app {:host ip :port port})))

    In the method, we fetch the IP address and the port from OpenShift environment variables. If variables are not defined, the server will use default values 0.0.0.0:8080. This will enable the server to start in the development environment.

    Run lein run to start the server. After the server has started, open http://localhost:8080 in a browser. You should see the “Hello World” message coming from the application.

    Now, commit changes and push to OpenShift:

    git add .
    git commit -m "Serve application with Jetty"
    git push

    After a few minutes, you should be able to see the “Hello World” message when you visit the application URL on OpenShift.

    Compojure web application running on OpenShift

    Congratulations, you now have a running Compojure application on OpenShift. Every time you push to the OpenShift remote, the application will be re-deployed.

    Deploying Existing Compojure Applications to OpenShift

    We showed how to create and deploy a new Compojure application to OpenShift. But, what if you already have an existing Compojure application whose code is already in a Git repository?

    The first step is to make sure the application server can be started with lein run.

    After that, you can use the rhc app create command with --from-code parameter that will point to an existing application repository:

    rhc app create myapp
    http://cartreflect-claytondev.rhcloud.com/github/strika/clojure-cartridge
    --from-code https://github.com/yourname/myapp.info.git
    

    This will create a new OpenShift application called myapp and checkout the repository to the myapp directory on the development machine. It will also set OpenShift to the origin remote, while the original repository will be set to the upstream remote.

    You can use the git push [remote-name] [branch-name] command to push to the OpenShift origin remote or the upstream remote. For example git push origin cool-new-feature would push cool-new-feature branch to the OpenShift origin remote and deploy the code so you can try it out.

    Conclusion

    In this tutorial we showed you how to create a Compojure application using the Leiningen template and how to create and deploy the application on OpenShift using the community-maintained Clojure cartridge. We also covered deploying an existing Compojure application.

    The cartridge we used is not tied to Compojure. It can be used to deploy Clojure applications based on other frameworks or libraries. The important prerequisite is that the application can be started with the lein run command.

    Leave a Reply

    Your email address will not be published. Required fields are marked *