In this post, you’ll learn how to deploy a Docker-based Clojure application to Heroku using the Heroku Docker CLI. We’ll use the Immutant Feature Demo as an example, but you can follow along with any Clojure application as long as it uses Leiningen to build an uberjar. This is a Mac and Linux guide only (until Docker supports
docker-compose on Windows).
You’ll need a few pieces of software before you get started:
- Docker (easily installed with the Docker Toolbox)
- Docker Compose (You’ll have this if you installed the Toolbox)
- Heroku Toolbelt
You’ll also need to create a free Heroku account. Then login from the terminal like so:
Once that’s complete, you can install the Heroku Docker CLI with this command:
Now you’re ready to deploy.
Deploying an App
To begin, clone the Immutant demo app to your local machine (if you’d prefer a bare-bones Clojure app you can substitute this Ring app):
The app is already prepared for Heroku. It contains a
Procfile, which tells Heroku how to run the app, and an
app.json file that contains some meta-data about the app. The important part of the
app.json file is the
"image" element, shown below:
"image" element is what Heroku uses to determine the base Docker image to run the container from.
"addons" element determines what additional services will be attached to your container. The Heroku
currently supports Postgres, Redis and a few others services with more to come.
Given this configuration, we can initialize the app with the following command:
This created a
Dockerfile based on the
heroku/clojure image and a
docker-compose.yml that constructs the environment (including a local database running in a Docker container).
Now run this command to start the application in a container:
The first time you run this it will take a while as Leiningen downloads the app’s dependencies into the Docker container. But don’t worry, they’ll be cached.
When the container has started, you’ll see some output like this:
That’s Immutant demonstrating it’s scheduling feature.
Open the app in a browser by running this command:
After you’ve played around with some of the features, like WebSockets, you can deploy the app to Heroku. First, provision a new app thusly:
And deploy to Heroku with the Docker CLI
Then you can open the app with this command:
Note that when using WebSockets in Firefox, you’ll need to use an
http:// addres instead of the
https:// that Heroku defaults to.
In your normal workflow, you’d want to make some changes and see them appear in the Docker container. We’ll demonstrate how that works. Open the
src/demo/scheduling.clj file and look for this code:
"beep" string on the first line to
Save the file, and then run these commands to rebuild the image:
Open the app in a browser again and navigate to the
/hello path. You’ll see your changes. Each time modify your app, you need to re-build the image and then launch the
up command. You can also get terminal access to the image by running the
shell command thusly:
From this shell, you can run one-off tasks like database migrations.
Heroku’s Docker support is currently in beta. As we work to make the integration better, we’d love to hear your feedback so we can focus on building the things you need. Feel free to reach out to me directly with you thoughts and ideas.
You can visit the Heroku Dev Center for more information on Heroku’s Docker CLI. And you can learn more about Immutant and Docker from their respective documentation sites. You can also find more information about deploying Clojure apps to Heroku on the Dev Center.