Running Clojure on Azure Websites

Running Clojure on Azure Websites

Lisp and Clojure in particular has long been on my list of languages to explore. Already having a MSDN subscription with monthly Azure credits it becomes the natural Cloud platform to explore. Instead of burdening oneself with managing additional machines, PaaS on Azure is a good alternative. Azure Websites, which has had support for Java since spring last year, is a particularly good alternative for exploring the Cloud applications via Clojure. However, I unable to find much documentation on how to deploy web applications running on the JVM on Azure Websites, in particular in continuous deployment scenarios.

Current documentation suggest manually uploading artifacts to Azure whereas .NET and Node.js applications have had support for continous deployment since June, 2012. In this post we will, using a template Clojure Compojure application, explore how to deploy JVM web applications to Azure Websites.

Setting up the environment

Before we move on to Clojure, we first need to enable Java support on websites. Using the Azure’s cross-platform command line interface we can after the initial setup create a Website with azure site create --location <location> <site-name> where <location> is any of the locations returned from azure site location list.

I was unable to find any documentation on how to enable Java or how to choose a container from the CLI. Also, at the time of writing, Java is disable by default and can only be enabled through the Azure manage portal in the General-section of the Configure-tab. As Compojure application uses Jetty by default, we need to make sure Jetty is the chosen container.

Ideally, we would want Azure Websites to automatically deploy the application from a source repository for each commit. “Set up deployment from source control” in the Dashboard-tab allows for a variety of options for deployment from source repositories, including from a Git repository on Azure and associating the website with a repository hosted on GitHub or BitBucket.

With deployments enabled we can move on to configuring Azure Websites to automate deployments of Clojure applications.

Custom Kudu deployment scripts

Kudu, the open sourced deployment engine that is responsible for deploying applications from source repositories to Azure Websites, has a flexible pipeline which allows for custom deployment scripts. These scripts are executed as Bash scripts or batch files by Kudu for each change that is committed to source control and thus leaving an extension point for building Clojure applications using Leiningen.

Deployment script templates can be generated using CLI with azure site deploymentscript. At the time of writing, no template is provided for JVM applications leaving us to write one based on the basic template which can be generated with azure site deploymentscript --basic from the root of the Compojure application.

The command generates two files: .deployment and deployment.{sh,cmd} where the former is a simple configuration file which determines how the latter is executed. On my OS X machine .deployment executes deployment.sh using bash. This behavior can be override using the -t-flag, e.g. azure site deploymentscript --basic -t batch to generate a batch deployment script.

Considering Azure Websites runs on Windows the presence of bash is somewhat of a surprise but bash shells would certainly be familiar to many Clojure developers.

Building a Clojure application

Unfortunately, Leiningen is not available by default on target machines and thus adds an additional step to the deployment process. Fortunately, Leiningen is easily installed using a bash script. Browsing through script we can identify Leiningen is self-installed by fetching the required .jar-file using either wget or curl.

I was unable to find any official documentation on what tools are available on target machines. Instead we can use the Debug console in Kudu to explore the hosting environment. The Debug console is available at https://<website-name>.scm.azurewebsites.net/DebugConsole/?shell=powershell. Through an interactive bash shell we can determine curl is available which satisfies the HTTP client dependency for the Leiningen script. JDK 1.7 is already installed on target machines making Leiningen and the resulting JVM application executable.

In order to build the application, we add a Build-section between the Setup and Deployment sections of deployment.sh. We first download the Leiningen bash script:

followed by using Leiningen to build an .war-file:

Defining the java.net.preferIPv4Stack system property is necessary due to Azure restrictions. As Leiningen relies on Maven which by default writes fetched artifacts to C:\.m2\repository on Windows. However, the C-drive is not writeable from Azure Websites, forcing us to configure a different path. Following the example from the annotated version of Leiningen’s project.clj we add the following to project.clj in the application root directory to set a different path for the local cache.

Deploying the build

The Deployment section of script template uses KuduSync by default which will copy newer files from the source to target directory and remove any files that are no longer present in the source from target directory. However, as we built a war-file during the build step the deployment step is therefore much easier:

With the changes to the deployment script, Azure Websites will download Leiningen if necessary and use it to build the Clojures application and lastly, copy the resulting artifact to the appropriate directory.

Conclusion

In this post we examined how to run an JVM application on Azure Websites and also how to configure websites to automatically and continuously deploy Clojure applications from a source repository to an Azure Website using a custom Kudu deployment script.

A sample project is available on GitHub.

Leave a Reply

Close Menu