How to Create Minimal Elixir Web App With Plug and Cowboy and Deploy to Heroku

This post will go through how to create a minimal web application in Elixir just using Cowboy, an HTTP server for Erlang/OTP, and Plug, a composable web middleware for Elixir, and deploy it to Heroku.

Since you are knowledgeable enough to know about and look for a barebone approach, I assume that you have a basic familiarity with both Elixir and web development.

I’m using Elixir 1.4.1 at the time of writing. The application directory structure and mix.exs file configuration got changed in Elixir 1.4, so I recommend you to get Elixir 1.4 or higher to minimize discrepancy.

Complete source code of the finished sample application can be found here. Link to the running Heroku app is here.

Create an Elixir Application

In this post, we will create a simple application that converts datetime between iso8601 and unix formats.

Run mix new timeconverter --sup from your shell to create a new Elixir app with built-in supervision tree.

Add HTTP Server

We will set up Cowboy and Plug. Open mix.exs and add dependencies.

Then run mix deps.get to fetch necessary dependencies.

After that, we will create Timeconverter.Router module that will serve as the HTTP interface of the application. Create router.ex in lib/timeconverter directory. Copy the following code into the newly created file.

Plug.Router provides a set of macros to generate routes that respond to HTTP reqeusts. When you use that module, match and dispatch plugs are required by default.

get "/" will respond to GET requests made to the root page. All other requests will be routed to match _.

Check the documentation for Plug.Router from here.

start_link/3 function is a part of GenServer, not Plug.Router. It defines what Timeconverter.Router module will do when it’s run under a supervision tree. Here we set it to run Cowboy under HTTP.

Next we will include Timeconverter.Router under the application’s supervision tree so that it will be run when the application runs. Open lib/timeconverter/application.ex and add Timeconverter.Router as a worker.

Now Cowboy HTTP server will also run when our application runs.

Run mix run --no-halt from the shell. If you are prompted to install rebar dependency, do so. When the application runs, open up localhost:4000. You will see the application running, greeting you with a simple text “wow!”.

Add Domain Logic for Converting Time Format

Since this post is about building a minimal web app and deploying it, we will not go into the domain logic itself. It’s a pretty boring example, anyway.

Replace the contents of lib/timeconverter.ex with the following code. Remember that this sample code is also provided on github.

Nothing interesting here - just some Regex and DateTime functions. Let’s look at how we connect the HTTP routes with domain logic. Open lib/timeconverter/router.ex and change the route functions.

Plug.Conn could be understood as the representation of HTTP requests and responses. All useful information about a single HTTP connection is stored in one Plug.Conn struct and can be accessed from there.

Query parameters can be accessed from conn.params only after running Plug.Conn.fetch_query_params/1. After getting the parameters, we pass conn.params to our domain logic function Timeconverter.convert_datetime/1. As you can see, connecting HTTP endpoint layer and domain logic is simple and straightforward.

Quit the application and run it again. Now the app will respond to different query parameters.

Deploying to Heroku

You need Heroku account and Heroku Command Line Interface for this part. If you haven’t set it up already, visit Heroku dev center and follow the instructions.

We need buildpacks to deploy to Heroku. Although Elixir is not officially supported, there’s an open source buildpack for Elixir created by HashNuke. We will use that buildpack to deploy to Heroku. Check the documentation for HashNuke’s buildpack from here.

But we need to make a few preparations before deploying. First create elixir_buildpack.config file in the application’s root directory and type the following configurations.

As of February 2017 the buildpack uses Elixir 1.3 when no Elixir version is specified. Since we’re using Elixir 1.4, the build causes error if we don’t specify the Elixir version we’d like to use.

Now open lib/timeconverter/router.ex file to set up port configuration for Heroku.

Heroku assigns a port through environment variable PORT. We need to get that port number through System.get_env("PORT") so that our application can run on Heroku. if clause in get_port/0 is there to provide port number when we would like to run our application locally.

Go to the root directory of our application. Then create a Heroku app with the buildpack by running heroku create --buildpack "https://github.com/HashNuke/heroku-buildpack-elixir.git".

The script will build the Heroku application and also set a git remote repository called heroku. Run git push heroku master to deploy the application to Heroku. Now your application is all set and running. Run heroku open to open the application in your browser and check if it’s running correctly.