Running Elixir Dynamo on Heroku

"Elixir is a functional meta-programming aware language built on top of the Erlang VM. It is a dynamic language with flexible syntax with macros support that leverages Erlang's abilities to build concurrent, distributed, fault-tolerant applications with hot code upgrades." - from http://elixir-lang.org

Elixir is a new ruby-like language created by Jose Valim, built on top of the Erlang VM. It’s caught my interest for a while now, but until recently has been too young for me to dive in much.

Dynamo is a web framework written and running on Elixir. Dynamo goals are performance, robustness and simplicity.

Naturally, I went about trying Dynamo out and wanted to get it running on Heroku, which proved to be pretty easy. We start by installing Elixir, checking out the Dynamo rep, and generating a project. From there we use the Elixir third-party buildpack1 and things should fall into place nicely.

Installing Elixir

The easiest way to install Elixir is with Homebrew. With each new Elixir release, Jose submits an updated formula for Elixir, which makes staying up to date easy.

Assuming you have Homebrew install:

1
2
3
4
5
$ brew install elixir
==> Downloading https://github.com/elixir-lang/elixir/archive/v0.9.3.tar.gz 
==> make
/Users/clint/Developer/Cellar/elixir/0.9.3: 273 files, 3.2M, built in 35 seconds
$

Dynamo requires rebar2 to compile things, and Elixir makes it easy to install with the included

1
mix
build tool:

1
2
3
$ mix local.rebar
* creating /Users/clint/.mix/rebar
$

Done!

Installing Dynamo

Dynamo, like Elixir, is alpha at this stage, so installation is pretty manual :/

Start by cloning the repository and getting the dependencies:

1
2
3
4
5
6
7
$ git clone git@github.com:elixir-lang/dynamo.git
Cloning into 'dynamo'...
remote: Counting objects:
...
Resolving deltas: 100% (2016/2016), done.
$ cd dynamo
$ MIX_ENV=test mix do deps.get, test

Now create a new project:

1
$ mix dynamo path/to/new/project

Done! You now have a new Dynamo project template at

1
path/to/new/project
. Change to that directory, get your dependencies, and start the server:

1
2
3
4
5
6
7
8
9
$ cd path/to/new/project
$ mix deps.get
* Getting dynamo [git: "git://github.com/elixir-lang/dynamo.git"]
[...]
* Getting cowboy [git: "git://github.com/extend/cowboy.git"]
[...]
* Compiling dynamo
$ mix server
Running DynamoExample.Dynamo at http://localhost:4000 with Cowboy on dev

Done!. Visit http://localhost:4000 to see your running Dynamo app! Type

1
cntrl+c
and then
1
a
to abort the server and get back to your shell.

Setup the Heroku app

In order to run Elixir on Heroku, you need to utilize Heroku’s awesome third party buildpacks feature by setting a custom

1
BUILDPACK_URL
environment variable. From the project directory, create a new Heroku app and specify the buildpack:

1
$ heroku create --buildpack "https://github.com/goshakkk/heroku-buildpack-elixir.git" [app_name]

If you already have a Heroku app created, you can just set the

1
BUILDPACK_URL
config var:

1
$ heroku config:add BUILDPACK_URL="https://github.com/goshakkk/heroku-buildpack-elixir.git" -a YOUR_APP

Specify Erlang/OTP and Elixir versions

The Elixir buildpack allows you to specify different Erlang versions, but Elixir requires Erlang/OTP version R15 or greater. Specify a preferred Erlang/OTP version for the buildpack by creating a

1
.preferred_otp_version
:

1
$ echo "OTP_R16B" > .preferred_otp_version

By default, the Elixir buildpack uses the master branch version of Elixir. You can specify a custom branch or tag name from the https://github.com/elixir-lang/elixir repository in the

1
.preferred_elixir_version
dotfile:

1
$ echo "master" > .preferred_elixir_version

Setup a Procfile

Heroku needs a Procfile in order to run your application. Create a Procfile with a

1
web
process defined:

1
$ echo 'web: MIX_ENV=prod mix server -p $PORT' > Procfile

Important Note: Single quotes are important here.

1
$PORT
is an environment variable supplied by Heroku. If you use double quotes in the above
1
echo
call, your local shell will try to interpolate the contents, and you’ll end up with
1
-p 
and not
1
-p $PORT
.

Deploy

Add and commit your changes, then push to Heroku:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ git add Procfile .preferred_otp_version .preferred_elixir_version  
$ git commit -m "Setup for Heroku"  
$ git push heroku [[master]-----> Fetching custom git buildpack... done
-----> Elixir app detected
-----> Using Erlang/OTP OTP_R16B
[..]

-----> Installing Rebar from buildpack
-----> Using Elixir master
[...]
   Compiled lib/dynamo_example/dynamo.ex
   Compiled web/routers/application_router.ex
   Generated DynamoExample.Dynamo.CompiledTemplates
   Generated dynamo_example.app
-----> Discovering process types
       Procfile declares types -> web

-----> Compiled slug size: 52.7MB
-----> Launching... done, v6
       http://dynamo-example.herokuapp.com deployed to Heroku

Done!

You now have a working Dynamo app on Heroku!

What’s next?

No idea. Elixir and Dynamo are both really young. While a native database interface is planned, there’s nothing out at the time of this writing. Personal attemps to use BossDB have failed. If I get it working, I’ll update here.

Until then, get hacking.

  1. https://github.com/goshakkk/heroku-buildpack-elixir 

  2. Rebar is a build-tool for Erlang projects, from the folks at Basho

@ctshryock

About

My name is Clint Shryock. I develop things in Go and Ruby. I live in central Missouri, where the weather is beautiful 4 months of the year.
+-----------------+
|                       |
|      (ノ^_^)ノ      |
|                       |
|   ☜(゚ヮ゚☜)    |
|                       |
|     ౿(ఠ_ఠఎ)    |
|                       |
|        ಠ_ಠ         |
x                      x
  xxx           xxx
       xx    xx
           xx