Skip to main content

Setup for production

There are many options to setup a lein ring project for production.

  • Deploy a WAR-archive to a Servlet engine like Tomcat or Jetty.
  • The plugin lein-ring and ring-server
  • Embedded Jetty Server
  • Embedded Jetty Server as part of a module system
  • Use one of the [[Third Party libraries]]

WAR archive

A WAR archive is the standard packaging to copy an application to an existing Tomcat or Jetty servlet engine.

It is a ZIP file with a specific structure containing the clojure code and all libraries.

Create the archive using the following command.

lein ring uberwar

Deploy the created archive to your servlet engine.

Lein-ring plugin

You need to add the lein-ring plugin to your profile.clj.

:plugins [[lein-ring "0.12.1"]]
:ring {:handler sample/handler}

In addition disable hot reloading and random port selection using the enviroment option.

LEIN_NO_DEV

Start the server.

LEIN_NO_DEV=true lein ring server-headless

More infos: https://github.com/weavejester/ring-server

Embedded Jetty server

We create a JAR file containing the already compiled Clojure code and all libraries.

Steps

  • src/sample.clj entrypoint of JAR
  • build configuration

Use ring.adapter.jetty to start Jetty with your handler.

(ns sample
(:require [ring.adapter.jetty :refer [run-jetty]])
(:gen-class))

(defn handler [request]
{:status 200
:headers {"Content-Type" "text/text"}
:body "Hello world"})

(defn -main [& args]
(run-jetty handler {:port (Integer/valueOf (or (System/getenv "port") "3000"))}))

It is important to use :gen-class with AOT compiling.

The next step depends on the build tooling.

Build using Leiningen

We need to add :aot and :main to the project.clj.

(defproject lein-ring "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.8.0"]
[ring/ring-core "1.6.3"]
[ring/ring-jetty-adapter "1.6.3"]
[ring/ring-devel "1.6.3"]]
:profiles{
:uberjar{
:aot :all
:main sample}})

Build using Boot

A simple build.boot containing a task to create an uberjar.

(set-env!
:resource-paths #{"src"}
:dependencies '[[org.clojure/clojure "1.8.0"]
[ring/ring-core "1.6.3"]
[ring/ring-jetty-adapter "1.6.3"]
[ring/ring-devel "1.6.3"]])

(deftask build
"Builds an uberjar of this project that can be run with java -jar"
[]
(comp
(aot :namespace #{'sample})
(uber)
(jar :file "project.jar" :main 'sample)
(sift :include #{#"project.jar"})
(target)))

Run the server

Execute the Jar File with an optional port.

port=2000 java -jar target/project.jar

Embedded Jetty Server as part of a module system

Have a look at the page about module lifecycle libraries [[Interactive Development]]