CircleCI Elixir setup
By: Marko Honkanen
Tags: Postgres, Elixir, Docker, Circleci

Photo by Carol Jeng on Unsplash

I’ve recently moved my projects from another cloud CI provider to CircleCI. I was familiar with CircleCI v1 from a previous project I was working on and decided to give v2 a try. The process of transferring the projects was a smooth one and I’m quite happy with the results and the speed of CI builds. Many of my projects are based on Elixir and Phoenix and this one is no exception. My requirements were to be able to build the project, have a Postgresql database available and be able to run Elixir based ExUnit tests as well as acceptance tests using JavaScript.

The builds can be configured in a couple of different ways. The first one is to create a stand-alone job, which can be one of several types but in this case, we are using build . There is a setup guide on the Circle CI website and there are other tutorials too which helped setting everything up.

Configuration

CircleCI 2 configuration is based solely on the circleci YAML file (.circleci/config.yml). This is good as your CI pipeline will be treated as code and you won’t run into the problem where the person who setup the Jenkins instance two years ago and knows how it works has left the company. Jenkins configuration can of course also be treated as code but with many of the cloud CI providers there is no other option.

Docker images

In this example, we use the Alpine Linux based Postgres 10 image. The environment variables define the values that can be used when connecting to the DB later on. Alpine Linux is a lightweight Docker image perfect for running services without too many dependencies and keeping the Docker images small for quick downloads.

The Elixir app is also going to be run in a Docker container. A Phoenix app usually contains some JavaScript (and other static assets), which needs to be installed by npm / yarn and handled by Webpack . If the front-end needs to be tested in the same box, having a browser available in the Docker image makes things easier as one doesn’t need to be installed separately. CircleCI has made an image available that suits these needs perfectly, i.e. elixir:node-browsers . It’s pulled in in the next config section shown below:

When the application runs, it needs to connect to the DB and it can do just by with the help of the DB name, user and password configured above. The keys/values under the environment key are set as part of the application environment and the application can pull in these values by defining the test configuration (config/test.exs) in the following way:

Ecto configuration

The local fallback values are optional and are used when the environment variable is not set. I typically use static values during development on the local machine.

The full configuration is available in this gist.

Caching

CircleCI supports caching to make it possible to reuse specific directories from a build. Anything to do with npm can be quite slow and being able to cache the assets is going to significantly speed up the builds. The configuration shown in the gist above has caching configured for both npm packages and Elixir dependencies. Much of the caching config is based on this blog post by Joe Ellis.

Summary

When adding a project to CircleCI, the UI suggests to create and push the config file to the repo and start building. The beauty of having a Yaml based CI configuration is that it’s easy as copying a file to get started.