For our latest project (photo duel site) we have decided to use the Clojure language. In order to make it easy for us at the beginning, we chose Heroku to host our application so that we don't have to manage deployment, hosting and database by ourselves.
So far I'm really happy about this choice, but nevertheless there were a few issues along the way. In order to reuse some CSS stuff and knowledge from our other project (Albumino) we had to find out how to compile our CSS files using Compass. So how do you do that when using Heroku? First let's look how your Clojure application is being built.
To deploy your application to Heroku you push all your source files to their Git repository. Heroku then builds and deploys your application. This process is language specific and so called buildpacks are used to support different languages.
Clojure is handled by
which builds project using Leiningen. But it's to no surprise that it
doesn't know how to build CSS files. :) Fortunately Clojure buildpack
is easily extensible using a custom build script which you can put into
For standard application it should contain:
#!/bin/bash lein with-profile production compile :all
In order to build our CSS we need
compass Ruby gem. By default it's
not installed on the machine where Heroku performs builds, so we need
to install it using
gem install compass. It will fail due to
permissions problem as it will try to install itself into system-wide
gem directory which is read-only. But that could be configured using
GEM_HOME environment variable.
#!/bin/bash export GEM_HOME=$PWD/gems mkdir -p $GEM_HOME gem install compass $GEM_HOME/bin/compass compile scss-dir css-dir lein with-profile production compile :all
To make build processes more predictable and repeatable you should use Bundler to manage required gems. It will make sure that you use the same versions of the gems for each build of your application.
You simply call
bundle init in the project's root directory and it
will create an example
Gemfile file. In our case we will modify it so
that it requires the
source "https://rubygems.org" gem "compass"
bundle install will than install all the required gems specified in
Gemfile and store their versions into
Gemfile.lock file for
In order to use bundler during build, you should modify your
bin/build script so that it installs bundler and calls
bundle exec wrapper.
gem install compass $GEM_HOME/bin/compass compile scss-dir css-dir
Should be changed to:
LC_ALL=en_US.UTF-8 gem install bundler # LC_ALL required by bundler $GEM_HOME/bin/bundle install $GEM_HOME/bin/bundle exec compass compile scss-dir css-dir
When you commit all the files (i.e.
Gemfile.lock) and push this change to Heroku you will find that the
build fails. The reason is that due to the presence of the
Heroku thinks that your application is using Ruby and not Clojure. The
fix is pretty easy though. You force Heroku to use Clojure buildpack
heroku config:set command.
heroku config:set BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-clojure
Your next push should succeed.
Thanks gfredericks and pandeiro (of #clojure fame) for the grammar check. :)