Photo - Kobi Li

Deploying Immutant to Wildfly

Currently, the tutorial on deploying to Wildfly with Immutant 2 is not written. Furthermore,the JBoss documentation isn't particularly tailored towards Clojure applications.

So, let's take a look at how to do this using the convenient dockerfiles provided by the JBoss project. We'll use Docker to simplify deployment and setup of Wildfly, but instructions for a non-docker application should be similar.

Create a basic Immutant application.

Starting from a lein new app learning command, set up your project like so:


(defproject learning "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url ""
  :license {:name "MPL"
            :url ""}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [org.immutant/immutant "2.x.incremental.186"]
                 [compojure "1.1.8"]]
  :repositories [["Immutant incremental builds"
  :plugins [[lein-immutant "2.0.0-SNAPSHOT"]]
  :ring {:handler learning.core/app}
  :main ^:skip-aot learning.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

Note how lein-immutant is in the :plugins field. This will give us access to the lein immutant <command> commands.


(ns learning.core
  (:use compojure.core)
  (:require [compojure.route    :as route]
            [immutant.web       :as immutant])

(defn handler
  "<h1>Hello World</h1>")

(defroutes app
  "The router."
  (GET "/learning/test" [] (handler))
       "<h1>Page not found</h1>"))

(defn -main
  "Start the server"
  [& args]
  (immutant/run app))

After speaking to the fine folks on the #immutant IRC channel on Freenode, we determined that Immutant seemed to have some issues with routing while running on JBoss. The route /learning/test should be just /test as far as I am able to tell, the problem will become apparent later.


FROM jboss/wildfly
RUN /opt/wildfly/bin/ hoverbear hunter2 --silent
ADD target/base+system+user+dev/learning.war /opt/wildfly/standalone/deployments/

Build the Immutant Application

Wildfly seems to expect .war files for deployment. Thankfully Immutant provides this via the plugin declared in the project.clj.

lein immutant war

The output should be similar to:

 lein immutant war
Compiling learning.core
Created /home/hoverbear/learning/target/uberjar/learning-0.1.0-SNAPSHOT.jar
Created /home/hoverbear/learning/target/uberjar/learning-0.1.0-SNAPSHOT-standalone.jar
Creating /home/hoverbear/learning/target/base+system+user+dev/learning.war

Notice how the resulting .war file is the same which is ADDed by the Dockerfile.

Building the Docker Image

Next, build the Docker image, make sure you're in the project directory.

docker build -t wildfly-learning .

If you haven't pulled the jboss/wildfly base image before, this first command might take awhile. Future builds will be very fast as it won't need to pull the base image.

Running the Container

docker run -p 8080:8080 -p 9990:9990 wildfly-learning

There should be a considerable log of output.


From there, you should be able to visit http://localhost:8080/learning/test and see "Hello World" in bold text. Visiting any other /learning/* url should yield a bold "Page not found" with a smaller 404 error underneath. Visiting a URL like /learn will give a different 404 page.

Visiting the Wildfly console

You should be able to visit http://localhost:9990/console/App.html and view the Wildfly admin interface, you might need to log in with details from the Dockerfile.

Browsing to the "Runtime > Manage Deployments" page will allow you to play with some settings.


This is, obviously, not a production deployment.