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:
- an account on GitHub for logging in to OpenShift
- an account on the next-gen preview of OpenShift Online
- the OpenShift command line interface (CLI)
- 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