Clojure "Hello World" on OpenShift

I've been a Lisp guy since undergraduate days, and in the JVM phase of my career that has meant Clojure. Though it's been many years since I coded as a day job, Clojure is my go-to for playing around to see how things work. This often makes for an extra bit of fun since there isn't always a previously-blazed path for Clojure.

As I was acquainting myself recently with OpenShift v3 I didn't find much out there in the way of how-to's or quickstarts for Clojure beyond v2, so I thought I'd share my notes on getting started in case there are any Clojurati looking to use OpenShift or maybe even Clojure newbies who might be that much more attracted to the language knowing that it's easy to do it on OpenShift.

This quickstart requires:

  1. an account on GitHub for logging in to OpenShift
  2. an account on the next-gen preview of OpenShift Online
  3. the OpenShift command line interface (CLI)
  4. Leiningen, the build automation tool that wraps Maven for Clojure projects

I've only tested this on a Mac, so I can't vouch for other platforms.

Part 1: Simple "Hello World"

The idea here is to get a simple Web app running on OpenShift that gives a "Hello World" Web page
I used the Compojure library, which has a nice integration with Leiningen such that you can start with

lein new compojure cpjhello

Now cd into the skeletal app you just created

cd cpjhello

Now edit the project.clj file to change the default port for the Web app from 3000 to 8080. Find the following line:

:ring {:handler cpjhello.handler/app}

and change it to

:ring {:handler cpjhello.handler/app :port 8080}

Now create the uberjar for upload to OpenShift:

lein ring uberjar

You also need to have the uberjar in a directory called deployments for OpenShift, so set that up:

mkdir deployments
mv target/cpjhello-0.1.0-SNAPSHOT-standalone.jar deployments/

Now get logged into OpenShift to prepare for and upload the app. Get your API token by browsing to

https://api.preview.openshift.com/oauth/token/request

and then login to OpenShift using the token as the token page shows, something like

oc login --token=<token_value_from_previous_step> --server=https://api.preview.openshift.com

Create an OpenShift project:

oc new-project testclj

For the remaining steps you can in parallel browse around in the OpenShift Console to see how the artifacts you create with the CLI are represented there.

Get the OpenJDK image that you'll use under your uberjar:

oc import-image my-redhat-openjdk-18/openjdk18-openshift --from=registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift --confirm

This should be a minute or two and end with --> Success in your terminal window

Ensuring you're still in the cpjhello directory with the deployment subdirectory where you put your uberjar, do

oc new-build --binary=true --name=cpjhelloworld -i=redhat-openjdk18-openshift

This may take a few minutes and should end with Push Successful. Now create the app:

oc new-app cpjhelloworld

which should complete quickly in the terminal with --> Success, though it will take a few minutes for the app to really start. You can observe this in the console and/or try in your terminal

oc get service

a few times until you see something like

NAME            CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE

cpjhelloworld 172.30.121.28 <none> 8080/TCP,8443/TCP,8778/TCP 1h

Now set up your route:

oc expose svc/myscal --port=8080

and find out what it is:

oc get route

which will give you an address like cpjhelloworld-testclj.44fs.preview.openshiftapps.com that you can copy and past into your browser. Note that you can also just click the route within the OpenShfit console. You should see your 'Hello World' and be stoked!

If you want to make some edits to the code and redeploy, make the edits e.g. to cpjhello/src/cpjhello/handler.cpj and then redo the following steps in the cpjhello directory:

lein ring uberjar
mv target/cpjhello-0.1.0-SNAPSHOT-standalone.jar deployments/
oc new-build --binary=true --name=cpjhelloworld -i=redhat-openjdk18-openshift

and then watch in the console as the app redeploys automatically after the new-build.

Part 2: adding nREPL

Now that you have an app up and running, the next thing you may want to do is what I think is one of the coolest things about working in Clojure: the ability to connect to a remote Clojure app with a REPL and view and edit the running app.

To set up nREPL, add the following to the :dependencies in your project.clj:

[org.clojure/tools.nrepl "0.2.12"]

and add the following to the :require in handler.clj:

[clojure.tools.nrepl.server :as nrepl]

as well as the following somewhere (e.g. the bottom) in handler.clj:

(defonce server (nrepl/start-server :port 7888))

Do your rebuild and redeploy as above, and once the app is up and running again, do the following in a terminal:

oc get pods

and find the pod name of your app, and then do a port-forward like this (swapping in your correct pod name):

oc port-forward cpjhelloworld-3-ln7ea 7888:7888

and you can now connect to the running app. I use the Cider package for Emacs, in which case you do

M-x cider-connect

answer the prompts with

127.0.0.1

and

7888

and

~/src/cpjhello

(or whatever your project directory is) which gets you a REPL in an Emacs buffer. Try

(in-ns 'cpjhello.handler)

and then just

app

and you should get something like #object[ring.middleware.x_headers$wrap_content_type_options$fn__4511 0x55ed305b "ring.middleware.x_headers$wrap_content_type_options$fn__4511@55ed305b"]

I put this simple app with the nREPL additions at https://github.com/mpiech/cpjhello in case something isn't working out and you want to double-check.

Have fun!


Categories

OpenShift Container Platform, Products, Technologies, OpenShift Dedicated, OpenShift Online

< Back to the blog