Building and Deploying your first Phoenix Application

Marcelo Risoli
Dec 5, 2016 · 5 min read

Disclaimer: I am still quite a beginner in Elixir and Phoenix and writing this is a way for me to learn as well as show some of the possible problems I’ve had, there are probably better ways to do most of the things done here

Elixir and Phoenix have been dubbed as successor to Ruby and Rails by many, both are heavily inspired by the former language and framework, and advertise speed relying on the battle-tested Erlang VM to attract developers who once struggled with Ruby performance.

While Rails is far from dead, Phoenix has been gaining momentum and an increasing number of companies have been adopting the Elixir-based framework for new projects, you can find a lot of articles around the web pointing to learning steps on Elixir and Phoenix, so while tools and libraries are still fairly limited when compared to the Ruby community, the developers are growing fond of it, and there is plenty of material to learn from.

Deployment of Elixir and Phoenix applications is still a little bit complicated, as Phoenix is still in its infancy and has changed quite a bit there are not that many simple deployment options as you have with more mature frameworks such as Rails.

In order to try deployment lets make a simple Phoenix application of a to-do list, much like you see at todomvc, it is a very simple CRUD application of a single model, a task that has a description and a status, it can be either active or completed, and you can edit tasks as well as mark them as complete or active.

For the purpose of this tutorial I won’t concern much about layout and will use Phoenix defaults, it won’t have the best usability, but that can be done later as improvements.

I am using Phoenix 1.2 and Elixir 1.3 and PostgreSQL 9.6, there may be differences in this process using others versions, specially older versions of Phoenix, besides this I will try to not use anything outside of the default Phoenix dependencies.

Project Setup

Project setup is pretty straightforward, first we generate a simple application:

mix phoenix.new todomvc

This will generate the Phoenix project, you will be prompted to install dependencies, if you decline you need to fetch dependencies later using mix deps.get.

This includes directories and Brunch to build assets, for this tutorial we do not strictly need Brunch, so you can also pass the no brunch option.

mix phoenix.new todomvc --no-brunch

After this you should commit to your version control system the initial project setup, now we can actually code the app itself

The tasks model

Since this is a very straightforward application we can use Phoenix html generator, which is quite similar to Rails Scaffold, like this, since status is a simple filter with two options we could also use a boolean or an integer for this, but I have learned that creating this types of fields as a string will make it more extensible in the future

mix phoenix.gen.html Task tasks description:string status:string

This will generate a model, a controller, a view, and templates for the task model, it will also generate tests for model and action in the controller, we’ll have to alter them a little to make more sense.

If we try to run the migration right now Mix will throw a Compile Error, this is because the path helper on the TasksController is mapped on the router file, so we first need to change the web/router.ex file to generate the helper for us, while at it, lets route the root path straight to the tasks controller, we can also remove the page controller and its tests

Small note for those coming from a rails background, while rails pluralizes controller names, Phoenix does not, this confused me a lot at the beginning.

We need to do some tweaks before migrating, since the user will not input status directly, first we change the migration file to set the default value:

Also change the model to set the default value on the Ecto Schema:

Also, lets change the valid attributes on controller and model tests to reflect we don’t need status to create a valid changeset for a Task:

@valid_attrs %{description: “some content”}

Finally, remember to remove the status field from the task form

If we run our tests, they should all pass.

We also need to add a button to update the status of the task, it should mark the task complete when its active or mark it active otherwise, we could do this easily with an if/else block on the template, but we can also use the power of pattern matching, it feels more Elixir-ish, so we create a helper function on the view:

Here we use pattern matching to define the button type, if we call this function with a task with active status it will match the first function and create a “Mark Complete” button, if we use a Task with status of complete it will match to the second and create a “Mark Active” button.

Lastly we need to be able to filter active and complete tasks, we can add some functions to query status on the model:

And we use pattern matching on the controller to apply the appropriate filter(or not):

We should also add some buttons so the user can easily filter using these scopes:

Our app may not be looking pretty right now but its functioning, lets call it an alpha and get ready to deploy it

Deploying a Phoenix Application to Heroku

Heroku is by far the easiest to deploy to, it has a free tier where you can experiment with your projects and it is covered in the official Phoenix guides, I pretty much just followed the instruction on the guide for this.

First, install the heroku toolbelt, than on the command line:

# first add the elixir buildpack$ heroku create --buildpack "https://github.com/HashNuke/heroku-buildpack-elixir.git"# then add the phoenix static assets buildpack$ heroku buildpacks:add https://github.com/gjaldon/heroku-buildpack-phoenix-static.git

Then change config/prod.exs to use environment variables, thus you won’t need the prod.secret.exs file being handed around when developing with multiple people:

Create the Procfile, the file which Heroku uses to run commands:

web: MIX_ENV=prod mix phoenix.server

Then setup the Heroku postgres application(hobby-dev is the free tier):

$ heroku addons:create heroku-postgresql:hobby-dev
$ heroku config:set POOL_SIZE=18

Then run the phoenix secret generator task to set up the secret_key_base used in the environment variable:

$ mix phoenix.gen.secret
$ heroku config:set SECRET_KEY_BASE="{place generated secret here}"

Commit everything, then push to heroku with

$ git push heroku master

Also run migrations, this is not done by default on the buildpack, once thats done, you can use the heroku toolbelt to open your app:

$ heroku run "POOL_SIZE=2 mix ecto.migrate"
$ heroku open

And you should see your first Phoenix Application in all its glory!

Note: The heroku Phoenix buildpack is meant to work with brunch and will throw an error if you’re not using, brunch, this has been discussed here, it can be done by running the command below, credits go to @ivorpaul for pointing this out.

$ heroku buildpacks:remove https://github.com/gjaldon/heroku-buildpack-phoenix-static.git

I’ve published a repo containing this todo example on my gitlab account, which you can find here.

In the future I hope to improve upon this, include more tests and add some CI utilities to automate deployment, follow me if you are interested in more Elixir or web development content in general!

More From Medium

Also tagged Phoenix Framework

Also tagged Phoenix Framework

Tutorial: Full Stack App

Feather
Mar 8 · 11 min read

87

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade